├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── wdevtools
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── me
│ │ │ └── ibrahimsn
│ │ │ └── wdevtools
│ │ │ ├── BaseApplication.kt
│ │ │ ├── di
│ │ │ ├── AppDataModule.kt
│ │ │ ├── AppDomainModule.kt
│ │ │ └── AppViewModelModule.kt
│ │ │ └── ui
│ │ │ └── MainActivity.kt
│ └── res
│ │ ├── drawable
│ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── ic_launcher_background.xml
│ │ └── strings.xml
│ └── test
│ └── java
│ └── me
│ └── ibrahimsn
│ └── wdevtools
│ └── ExampleUnitTest.kt
├── art
├── 1.png
├── 2.png
├── 3.png
└── 4.png
├── build.gradle
├── buildSrc
├── build.gradle.kts
├── build
│ ├── classes
│ │ └── kotlin
│ │ │ └── main
│ │ │ ├── CoreLibraries.class
│ │ │ ├── Libraries.class
│ │ │ ├── META-INF
│ │ │ └── buildSrc.kotlin_module
│ │ │ ├── Modules.class
│ │ │ ├── Plugins.class
│ │ │ ├── SupportLibraries.class
│ │ │ └── Versions.class
│ ├── kotlin
│ │ ├── buildSrcjar-classes.txt
│ │ └── compileKotlin
│ │ │ ├── build-history.bin
│ │ │ ├── caches-jvm
│ │ │ ├── inputs
│ │ │ │ ├── source-to-output.tab
│ │ │ │ ├── source-to-output.tab.keystream
│ │ │ │ ├── source-to-output.tab.keystream.len
│ │ │ │ ├── source-to-output.tab.len
│ │ │ │ ├── source-to-output.tab.values.at
│ │ │ │ ├── source-to-output.tab_i
│ │ │ │ └── source-to-output.tab_i.len
│ │ │ ├── jvm
│ │ │ │ └── kotlin
│ │ │ │ │ ├── class-fq-name-to-source.tab
│ │ │ │ │ ├── class-fq-name-to-source.tab.keystream
│ │ │ │ │ ├── class-fq-name-to-source.tab.keystream.len
│ │ │ │ │ ├── class-fq-name-to-source.tab.len
│ │ │ │ │ ├── class-fq-name-to-source.tab.values.at
│ │ │ │ │ ├── class-fq-name-to-source.tab_i
│ │ │ │ │ ├── class-fq-name-to-source.tab_i.len
│ │ │ │ │ ├── constants.tab
│ │ │ │ │ ├── constants.tab.keystream
│ │ │ │ │ ├── constants.tab.keystream.len
│ │ │ │ │ ├── constants.tab.len
│ │ │ │ │ ├── constants.tab.values.at
│ │ │ │ │ ├── constants.tab_i
│ │ │ │ │ ├── constants.tab_i.len
│ │ │ │ │ ├── internal-name-to-source.tab
│ │ │ │ │ ├── internal-name-to-source.tab.keystream
│ │ │ │ │ ├── internal-name-to-source.tab.keystream.len
│ │ │ │ │ ├── internal-name-to-source.tab.len
│ │ │ │ │ ├── internal-name-to-source.tab.values.at
│ │ │ │ │ ├── internal-name-to-source.tab_i
│ │ │ │ │ ├── internal-name-to-source.tab_i.len
│ │ │ │ │ ├── proto.tab
│ │ │ │ │ ├── proto.tab.keystream
│ │ │ │ │ ├── proto.tab.keystream.len
│ │ │ │ │ ├── proto.tab.len
│ │ │ │ │ ├── proto.tab.values.at
│ │ │ │ │ ├── proto.tab_i
│ │ │ │ │ ├── proto.tab_i.len
│ │ │ │ │ ├── source-to-classes.tab
│ │ │ │ │ ├── source-to-classes.tab.keystream
│ │ │ │ │ ├── source-to-classes.tab.keystream.len
│ │ │ │ │ ├── source-to-classes.tab.len
│ │ │ │ │ ├── source-to-classes.tab.values.at
│ │ │ │ │ ├── source-to-classes.tab_i
│ │ │ │ │ └── source-to-classes.tab_i.len
│ │ │ └── lookups
│ │ │ │ ├── counters.tab
│ │ │ │ ├── file-to-id.tab
│ │ │ │ ├── file-to-id.tab.keystream
│ │ │ │ ├── file-to-id.tab.keystream.len
│ │ │ │ ├── file-to-id.tab.len
│ │ │ │ ├── file-to-id.tab.values.at
│ │ │ │ ├── file-to-id.tab_i
│ │ │ │ ├── file-to-id.tab_i.len
│ │ │ │ ├── id-to-file.tab
│ │ │ │ ├── id-to-file.tab.keystream
│ │ │ │ ├── id-to-file.tab.keystream.len
│ │ │ │ ├── id-to-file.tab.len
│ │ │ │ ├── id-to-file.tab.values.at
│ │ │ │ ├── id-to-file.tab_i
│ │ │ │ ├── id-to-file.tab_i.len
│ │ │ │ ├── lookups.tab
│ │ │ │ ├── lookups.tab.keystream
│ │ │ │ ├── lookups.tab.keystream.len
│ │ │ │ ├── lookups.tab.len
│ │ │ │ ├── lookups.tab.values.at
│ │ │ │ ├── lookups.tab_i
│ │ │ │ └── lookups.tab_i.len
│ │ │ └── last-build.bin
│ ├── libs
│ │ └── buildSrc.jar
│ ├── pluginUnderTestMetadata
│ │ └── plugin-under-test-metadata.properties
│ ├── reports
│ │ └── task-properties
│ │ │ └── report.txt
│ └── tmp
│ │ └── jar
│ │ └── MANIFEST.MF
└── src
│ └── main
│ └── java
│ ├── Dependencies.kt
│ ├── Modules.kt
│ ├── Plugins.kt
│ └── Versions.kt
├── common.gradle
├── core
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── core
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── me
│ │ │ └── ibrahimsn
│ │ │ └── core
│ │ │ ├── data
│ │ │ ├── dao
│ │ │ │ ├── RequestDao.kt
│ │ │ │ └── WebsocketDao.kt
│ │ │ ├── database
│ │ │ │ ├── AppDatabase.kt
│ │ │ │ └── Converters.kt
│ │ │ ├── di
│ │ │ │ ├── DataModule.kt
│ │ │ │ ├── HttpModule.kt
│ │ │ │ ├── RequestDataModule.kt
│ │ │ │ ├── UriDataModule.kt
│ │ │ │ └── WebsocketDataModule.kt
│ │ │ ├── model
│ │ │ │ ├── DataHolder.kt
│ │ │ │ ├── DefaultTextWatcher.kt
│ │ │ │ ├── ErrorHolder.kt
│ │ │ │ └── RequestMethod.kt
│ │ │ ├── repository
│ │ │ │ ├── RequestRepositoryImpl.kt
│ │ │ │ ├── UriRepositoryImpl.kt
│ │ │ │ └── WebsocketRepositoryImpl.kt
│ │ │ └── source
│ │ │ │ └── DefaultPreferences.kt
│ │ │ ├── domain
│ │ │ ├── Constants.kt
│ │ │ ├── di
│ │ │ │ ├── RequestDomainModule.kt
│ │ │ │ ├── UriDomainModule.kt
│ │ │ │ └── WebsocketDomainModule.kt
│ │ │ ├── interactor
│ │ │ │ ├── Interactor.kt
│ │ │ │ ├── request
│ │ │ │ │ ├── DeleteRequestsInteractor.kt
│ │ │ │ │ ├── GetAllRequestsInteractor.kt
│ │ │ │ │ ├── MakeRequestInteractor.kt
│ │ │ │ │ └── SaveOrUpdateRequestInteractor.kt
│ │ │ │ ├── uri
│ │ │ │ │ ├── GenerateUriInteractor.kt
│ │ │ │ │ └── ParseUriParamsInteractor.kt
│ │ │ │ └── websocket
│ │ │ │ │ ├── ConnectWebsocketInteractor.kt
│ │ │ │ │ ├── DeleteWebsocketsInteractor.kt
│ │ │ │ │ ├── GetAllWebsocketsInteractor.kt
│ │ │ │ │ └── SaveOrUpdateWebsocketInteractor.kt
│ │ │ ├── model
│ │ │ │ ├── param
│ │ │ │ │ └── Param.kt
│ │ │ │ ├── request
│ │ │ │ │ ├── Request.kt
│ │ │ │ │ └── RequestResponse.kt
│ │ │ │ └── websocket
│ │ │ │ │ ├── Websocket.kt
│ │ │ │ │ └── WebsocketEvent.kt
│ │ │ ├── repository
│ │ │ │ ├── RequestRepository.kt
│ │ │ │ ├── UriRepository.kt
│ │ │ │ └── WebsocketRepository.kt
│ │ │ └── source
│ │ │ │ └── LocalDataSource.kt
│ │ │ └── presentation
│ │ │ ├── Constants.kt
│ │ │ ├── base
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseAdapter.kt
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BasePagedAdapter.kt
│ │ │ ├── BaseViewHolder.kt
│ │ │ └── BaseViewModel.kt
│ │ │ ├── extension
│ │ │ ├── AdExt.kt
│ │ │ ├── CoroutineScopeExt.kt
│ │ │ ├── DateExt.kt
│ │ │ ├── GsonExt.kt
│ │ │ ├── LifecycleExt.kt
│ │ │ ├── LiveDataExt.kt
│ │ │ ├── RequestExt.kt
│ │ │ ├── StringExt.kt
│ │ │ ├── ViewExt.kt
│ │ │ └── WebsocketExt.kt
│ │ │ ├── livedata
│ │ │ └── SingleLiveEvent.kt
│ │ │ ├── model
│ │ │ └── ConsentManager.kt
│ │ │ ├── ui
│ │ │ └── param
│ │ │ │ └── ParamAdapter.kt
│ │ │ └── view
│ │ │ ├── progressButton
│ │ │ └── ProgressButton.kt
│ │ │ └── tabView
│ │ │ ├── TabItem.kt
│ │ │ ├── TabParser.kt
│ │ │ └── TabView.kt
│ └── res
│ │ ├── drawable
│ │ ├── ic_add_white_24dp.xml
│ │ ├── ic_background_box.xml
│ │ ├── ic_background_method.xml
│ │ ├── ic_background_method_delete.xml
│ │ ├── ic_background_method_get.xml
│ │ ├── ic_background_method_patch.xml
│ │ ├── ic_background_method_post.xml
│ │ ├── ic_background_method_put.xml
│ │ ├── ic_background_param_button.xml
│ │ ├── ic_background_response_status_fail.xml
│ │ ├── ic_background_response_status_success.xml
│ │ ├── ic_background_row.xml
│ │ ├── ic_close_white_18dp.xml
│ │ ├── ic_close_white_20dp.xml
│ │ ├── ic_close_white_24dp.xml
│ │ ├── ic_delete_white_24dp.xml
│ │ ├── ic_expand_less_white_24dp.xml
│ │ ├── ic_expand_more_white_24dp.xml
│ │ ├── ic_keyboard_arrow_right_white_18dp.xml
│ │ ├── ic_send_white_20dp.xml
│ │ └── ic_send_white_24dp.xml
│ │ ├── font
│ │ ├── lato.xml
│ │ ├── lato_bold.ttf
│ │ └── lato_regular.ttf
│ │ ├── layout
│ │ └── row_param.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── me
│ └── ibrahimsn
│ └── core
│ └── ExampleUnitTest.kt
├── feature
├── dashboard
│ ├── .gitignore
│ ├── build.gradle
│ ├── consumer-rules.pro
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── me
│ │ │ └── ibrahimsn
│ │ │ └── dashboard
│ │ │ └── ExampleInstrumentedTest.kt
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── me
│ │ │ │ └── ibrahimsn
│ │ │ │ └── dashboard
│ │ │ │ ├── di
│ │ │ │ └── DashboardViewModelModule.kt
│ │ │ │ └── presentation
│ │ │ │ ├── dashboard
│ │ │ │ ├── DashboardFragment.kt
│ │ │ │ ├── DashboardViewModel.kt
│ │ │ │ ├── RequestsAdapter.kt
│ │ │ │ └── WebsocketsAdapter.kt
│ │ │ │ ├── home
│ │ │ │ └── HomeActivity.kt
│ │ │ │ └── settings
│ │ │ │ ├── SettingsActivity.kt
│ │ │ │ └── SettingsFragment.kt
│ │ └── res
│ │ │ ├── layout
│ │ │ ├── activity_home.xml
│ │ │ ├── activity_settings.xml
│ │ │ ├── fragment_dashboard.xml
│ │ │ ├── fragment_settings.xml
│ │ │ ├── row_rest.xml
│ │ │ └── row_ws.xml
│ │ │ ├── menu
│ │ │ ├── menu_action.xml
│ │ │ ├── menu_home.xml
│ │ │ └── menu_tabs.xml
│ │ │ ├── values
│ │ │ └── strings.xml
│ │ │ └── xml
│ │ │ └── settings.xml
│ │ └── test
│ │ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── dashboard
│ │ └── ExampleUnitTest.kt
├── request
│ ├── .gitignore
│ ├── build.gradle
│ ├── consumer-rules.pro
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── me
│ │ │ └── ibrahimsn
│ │ │ └── request
│ │ │ └── ExampleInstrumentedTest.kt
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── me
│ │ │ │ └── ibrahimsn
│ │ │ │ └── request
│ │ │ │ ├── di
│ │ │ │ └── RequestViewModelModule.kt
│ │ │ │ └── presentation
│ │ │ │ └── request
│ │ │ │ ├── RequestFragment.kt
│ │ │ │ └── RequestViewModel.kt
│ │ └── res
│ │ │ ├── layout
│ │ │ └── fragment_rest.xml
│ │ │ └── menu
│ │ │ └── menu_request_method.xml
│ │ └── test
│ │ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── request
│ │ └── ExampleUnitTest.kt
└── websocket
│ ├── .gitignore
│ ├── build.gradle
│ ├── consumer-rules.pro
│ ├── proguard-rules.pro
│ └── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── websocket
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── me
│ │ │ └── ibrahimsn
│ │ │ └── websocket
│ │ │ ├── di
│ │ │ └── WebsocketViewModelModule.kt
│ │ │ └── presentation
│ │ │ └── websocket
│ │ │ ├── WebsocketFragment.kt
│ │ │ └── WebsocketViewModel.kt
│ └── res
│ │ └── layout
│ │ └── fragment_ws.xml
│ └── test
│ └── java
│ └── me
│ └── ibrahimsn
│ └── websocket
│ └── ExampleUnitTest.kt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── navigation
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── ibrahimsn
│ │ └── navigation
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ └── res
│ │ ├── navigation
│ │ └── nav_graph.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── me
│ └── ibrahimsn
│ └── navigation
│ └── ExampleUnitTest.kt
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | /.idea
16 | /app/google-services.json
17 | /.gradle
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Web Developer Tools Android
2 |
3 | Sample Android Application - MVVM, Clean Architecture, Modularization, Repository Pattern
4 |
5 |
6 | ## Tech Stack
7 | ```
8 | - Kotlin
9 | - MVVM
10 | - Modularization
11 | - Repository Pattern
12 | - Coroutines
13 | - Koin
14 | - Architecture Components
15 | - Navigation Component
16 | - LiveData
17 | - Paging
18 | - Kotlin DSL
19 | - OkHttp3
20 | ```
21 |
22 | ## Screenshots
23 |
24 |
25 |
26 |
27 | |
28 |
29 |
30 | |
31 |
32 |
33 | |
34 |
35 |
36 | |
37 |
38 |
39 |
40 |
41 | ## Google Play
42 | Download Web Dev Tools from [Google Play](https://play.google.com/store/apps/details?id=me.ibrahimsn.wdevtools).
43 |
44 |
45 | ## License
46 | Licensed under [GNU AGPLv3](https://github.com/ibrahimsn98/web-dev-tools-android/blob/master/LICENSE)
47 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidApplication
2 | apply from: "$rootDir/common.gradle"
3 | apply plugin: Plugins.crashlytics
4 | apply plugin: Plugins.googleServices
5 |
6 | android {
7 | defaultConfig {
8 | applicationId "me.ibrahimsn.wdevtools"
9 | }
10 | }
11 |
12 | dependencies {
13 | implementation fileTree(dir: 'libs', include: ['*.jar'])
14 | implementation CoreLibraries.kotlin
15 |
16 | implementation project(Modules.core)
17 | implementation project(Modules.navigation)
18 |
19 | implementation project(Modules.dashboard)
20 | implementation project(Modules.request)
21 | implementation project(Modules.websocket)
22 | }
23 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | -keep class com.google.firebase.** { *; }
24 | -dontwarn okhttp3.**
25 | -dontwarn okio.**
26 | -keep class com.crashlytics.sdk.android.** { *; }
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/ibrahimsn/wdevtools/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.wdevtools", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/java/me/ibrahimsn/wdevtools/BaseApplication.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools
2 |
3 | import android.app.Application
4 | import me.ibrahimsn.core.domain.source.LocalDataSource
5 | import me.ibrahimsn.core.presentation.model.ConsentManager
6 | import me.ibrahimsn.wdevtools.di.appDataModule
7 | import me.ibrahimsn.wdevtools.di.appDomainModule
8 | import me.ibrahimsn.wdevtools.di.appViewModelModule
9 | import org.koin.android.ext.android.inject
10 | import org.koin.android.ext.koin.androidContext
11 | import org.koin.android.ext.koin.androidLogger
12 | import org.koin.core.context.startKoin
13 |
14 | class BaseApplication : Application() {
15 |
16 | private val preferences: LocalDataSource.Preferences by inject()
17 |
18 | override fun onCreate() {
19 | super.onCreate()
20 | startInject()
21 | onInject()
22 | }
23 |
24 | private fun startInject() {
25 | val appModules = appDataModule + appDomainModule + appViewModelModule
26 | startKoin {
27 | androidLogger()
28 | androidContext(this@BaseApplication)
29 | modules(appModules)
30 | }
31 | }
32 |
33 | private fun onInject() {
34 | ConsentManager.setupPreferences(preferences)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/me/ibrahimsn/wdevtools/di/AppDataModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools.di
2 |
3 | import me.ibrahimsn.core.data.di.*
4 |
5 | val appDataModule = listOf(
6 | dataModule,
7 | httpModule,
8 | requestDataModule,
9 | websocketDataModule,
10 | uriDataModule
11 | )
12 |
--------------------------------------------------------------------------------
/app/src/main/java/me/ibrahimsn/wdevtools/di/AppDomainModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools.di
2 |
3 | import me.ibrahimsn.core.domain.di.requestDomainModule
4 | import me.ibrahimsn.core.domain.di.uriDomainModule
5 | import me.ibrahimsn.core.domain.di.websocketDomainModule
6 |
7 | val appDomainModule = listOf(
8 | requestDomainModule,
9 | websocketDomainModule,
10 | uriDomainModule
11 | )
12 |
--------------------------------------------------------------------------------
/app/src/main/java/me/ibrahimsn/wdevtools/di/AppViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools.di
2 |
3 | import me.ibrahimsn.dashboard.di.dashboardViewModelModule
4 | import me.ibrahimsn.request.di.requestViewModelModule
5 | import me.ibrahimsn.websocket.di.websocketViewModelModule
6 |
7 | val appViewModelModule = listOf(
8 | dashboardViewModelModule,
9 | requestViewModelModule,
10 | websocketViewModelModule
11 | )
12 |
--------------------------------------------------------------------------------
/app/src/main/java/me/ibrahimsn/wdevtools/ui/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools.ui
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 | import me.ibrahimsn.wdevtools.R
7 | import me.ibrahimsn.dashboard.presentation.home.HomeActivity
8 |
9 | class MainActivity : AppCompatActivity() {
10 |
11 | override fun onCreate(savedInstanceState: Bundle?) {
12 | super.onCreate(savedInstanceState)
13 | startActivity(Intent(this, HomeActivity::class.java))
14 | finish()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3EB63E
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Dev Tools
3 |
4 |
--------------------------------------------------------------------------------
/app/src/test/java/me/ibrahimsn/wdevtools/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.wdevtools
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/art/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/art/1.png
--------------------------------------------------------------------------------
/art/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/art/2.png
--------------------------------------------------------------------------------
/art/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/art/3.png
--------------------------------------------------------------------------------
/art/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/art/4.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.72'
5 | repositories {
6 | google()
7 | jcenter()
8 | maven { url 'https://jitpack.io' }
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.6.3'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 | classpath 'com.google.gms:google-services:4.3.3'
14 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0'
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | google()
23 | jcenter()
24 | maven { url 'https://jitpack.io' }
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.gradle.kotlin.dsl.`kotlin-dsl`
2 |
3 | plugins {
4 | `kotlin-dsl`
5 | }
6 |
7 | repositories {
8 | jcenter()
9 | }
10 |
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/CoreLibraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/CoreLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Libraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/Libraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/META-INF/buildSrc.kotlin_module:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Modules.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/Modules.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Plugins.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/Plugins.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/SupportLibraries.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/SupportLibraries.class
--------------------------------------------------------------------------------
/buildSrc/build/classes/kotlin/main/Versions.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/classes/kotlin/main/Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/buildSrcjar-classes.txt:
--------------------------------------------------------------------------------
1 | /home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/CoreLibraries.class:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/Libraries.class:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/Modules.class:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/Plugins.class:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/SupportLibraries.class:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main/Versions.class
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/build-history.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/build-history.bin
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.keystream:
--------------------------------------------------------------------------------
1 | Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Modules.kt^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.ktY/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Plugins.ktZ/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Versions.kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.keystream.len:
--------------------------------------------------------------------------------
1 | n
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/inputs/source-to-output.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len:
--------------------------------------------------------------------------------
1 | B
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.kt_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.kt_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.ktZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Modules.ktZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Plugins.kt[ Z/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Versions.kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream:
--------------------------------------------------------------------------------
1 |
CoreLibrariesSupportLibraries LibrariesModulesPluginsVersions
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream.len:
--------------------------------------------------------------------------------
1 | B
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/constants.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len:
--------------------------------------------------------------------------------
1 | B
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.kt_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.kt_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.ktZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Modules.ktZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Plugins.kt[ Z/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Versions.kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream:
--------------------------------------------------------------------------------
1 |
CoreLibrariesSupportLibraries LibrariesModulesPluginsVersions.kotlin_module
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream.len:
--------------------------------------------------------------------------------
1 | Q
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.values.at:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab.values.at
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/proto.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len:
--------------------------------------------------------------------------------
1 | n
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage Modules.kotlin_module8
CoreLibrariesSupportLibraries Libraries.kotlin_module Plugins.kotlin_module Versions.kotlin_module
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/counters.tab:
--------------------------------------------------------------------------------
1 | 4
2 | 0
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.keystream:
--------------------------------------------------------------------------------
1 | Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Plugins.ktY/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Modules.kt^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.ktZ/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Versions.kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.keystream.len:
--------------------------------------------------------------------------------
1 | n
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/file-to-id.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.keystream:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.keystream.len:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorageZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Plugins.ktZ Y/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Modules.kt_ ^/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Dependencies.kt[ Z/home/melianor/Android Projects/open-source/webdevtools/buildSrc/src/main/java/Versions.kt
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/id-to-file.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.keystream.len:
--------------------------------------------------------------------------------
1 | (
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab.values.at:
--------------------------------------------------------------------------------
1 | / Header Record For PersistentHashMapValueStorage
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i.len:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/caches-jvm/lookups/lookups.tab_i.len
--------------------------------------------------------------------------------
/buildSrc/build/kotlin/compileKotlin/last-build.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/kotlin/compileKotlin/last-build.bin
--------------------------------------------------------------------------------
/buildSrc/build/libs/buildSrc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/libs/buildSrc.jar
--------------------------------------------------------------------------------
/buildSrc/build/pluginUnderTestMetadata/plugin-under-test-metadata.properties:
--------------------------------------------------------------------------------
1 | implementation-classpath=/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/java/main\:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/groovy/main\:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/classes/kotlin/main\:/home/melianor/Android Projects/open-source/webdevtools/buildSrc/build/resources/main
2 |
--------------------------------------------------------------------------------
/buildSrc/build/reports/task-properties/report.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/buildSrc/build/reports/task-properties/report.txt
--------------------------------------------------------------------------------
/buildSrc/build/tmp/jar/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 |
3 |
--------------------------------------------------------------------------------
/buildSrc/src/main/java/Dependencies.kt:
--------------------------------------------------------------------------------
1 | object CoreLibraries {
2 | const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlinVersion}"
3 | }
4 |
5 | object SupportLibraries {
6 | const val core = "androidx.core:core-ktx:${Versions.coreVersion}"
7 | const val appCompat = "androidx.appcompat:appcompat:${Versions.appCompatVersion}"
8 | const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintVersion}"
9 | const val preference = "androidx.preference:preference-ktx:${Versions.preferenceVersion}"
10 | }
11 |
12 | object Libraries {
13 | const val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutinesVersion}"
14 | const val coroutinesAndroid = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutinesVersion}"
15 |
16 | const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:${Versions.lifecycleVersion}"
17 | const val lifecycleViewModel = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycleVersion}"
18 | const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:${Versions.lifecycleVersion}"
19 |
20 | const val navigation = "androidx.navigation:navigation-fragment-ktx:${Versions.navigationVersion}"
21 | const val navigationUi = "androidx.navigation:navigation-ui-ktx:${Versions.navigationVersion}"
22 |
23 | const val koin = "org.koin:koin-core:${Versions.koinVersion}"
24 | const val koinScope = "org.koin:koin-androidx-scope:${Versions.koinVersion}"
25 | const val koinViewModel = "org.koin:koin-androidx-viewmodel:${Versions.koinVersion}"
26 | const val koinAndroidExt = "org.koin:koin-androidx-ext:${Versions.koinVersion}"
27 |
28 | const val room = "androidx.room:room-runtime:${Versions.roomVersion}"
29 | const val roomKtx = "androidx.room:room-ktx:${Versions.roomVersion}"
30 | const val roomCompiler = "androidx.room:room-compiler:${Versions.roomVersion}"
31 |
32 | const val paging = "androidx.paging:paging-runtime:${Versions.pagingVersion}"
33 |
34 | const val firebaseAnalytics = "com.google.firebase:firebase-analytics:${Versions.firebaseAnalyticsVersion}"
35 | const val firebaseCrashlytics = "com.google.firebase:firebase-crashlytics:${Versions.crashlyticsVersion}"
36 | const val firebaseAds = "com.google.android.gms:play-services-ads:${Versions.firebaseAdsVersion}"
37 | const val consent = "com.google.android.ads.consent:consent-library:${Versions.consentVersion}"
38 |
39 | const val okHttp = "com.squareup.okhttp3:okhttp:${Versions.okHttpVersion}"
40 | const val gson = "com.google.code.gson:gson:${Versions.gsonVersion}"
41 | }
42 |
--------------------------------------------------------------------------------
/buildSrc/src/main/java/Modules.kt:
--------------------------------------------------------------------------------
1 | object Modules {
2 |
3 | const val app = ":app"
4 | const val core = ":core"
5 | const val navigation = ":navigation"
6 |
7 | const val dashboard = ":feature:dashboard"
8 | const val request = ":feature:request"
9 | const val websocket = ":feature:websocket"
10 | }
11 |
--------------------------------------------------------------------------------
/buildSrc/src/main/java/Plugins.kt:
--------------------------------------------------------------------------------
1 | object Plugins {
2 |
3 | const val androidApplication = "com.android.application"
4 | const val kotlinAndroid = "kotlin-android"
5 | const val androidLibrary = "com.android.library"
6 | const val kotlinAndroidExtensions = "kotlin-android-extensions"
7 | const val kotlinKapt = "kotlin-kapt"
8 | const val crashlytics = "com.google.firebase.crashlytics"
9 | const val googleServices = "com.google.gms.google-services"
10 | }
11 |
--------------------------------------------------------------------------------
/buildSrc/src/main/java/Versions.kt:
--------------------------------------------------------------------------------
1 | object Versions {
2 |
3 | const val kotlinVersion = "1.3.71"
4 |
5 | const val coreVersion = "1.2.0"
6 | const val appCompatVersion = "1.1.0"
7 | const val constraintVersion = "1.1.3"
8 | const val preferenceVersion = "1.1.0"
9 |
10 | const val coroutinesVersion = "1.3.3"
11 | const val lifecycleVersion = "2.2.0"
12 | const val navigationVersion = "2.3.0-alpha04"
13 | const val koinVersion = "2.1.4"
14 | const val pagingVersion = "2.1.2"
15 | const val roomVersion = "2.2.5"
16 |
17 | const val firebaseAnalyticsVersion = "17.2.3"
18 | const val crashlyticsVersion = "17.0.0-beta02"
19 | const val firebaseAdsVersion = "19.1.0"
20 | const val consentVersion = "1.0.8"
21 |
22 | const val okHttpVersion = "4.6.0"
23 | const val gsonVersion = "2.8.6"
24 | }
25 |
--------------------------------------------------------------------------------
/common.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.kotlinAndroid
2 | apply plugin: Plugins.kotlinAndroidExtensions
3 | apply plugin: Plugins.kotlinKapt
4 |
5 | android {
6 | compileSdkVersion 29
7 | buildToolsVersion "29.0.2"
8 |
9 | defaultConfig {
10 | minSdkVersion 21
11 | targetSdkVersion 29
12 | versionCode 9
13 | versionName "1.0.8"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled true
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | kotlinOptions {
26 | jvmTarget = "1.8"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidLibrary
2 | apply from: "$rootDir/common.gradle"
3 |
4 | dependencies {
5 | api CoreLibraries.kotlin
6 |
7 | api SupportLibraries.core
8 | api SupportLibraries.preference
9 | api SupportLibraries.appCompat
10 | api SupportLibraries.constraintLayout
11 |
12 | api Libraries.koin
13 | api Libraries.koinViewModel
14 | api Libraries.koinScope
15 |
16 | api Libraries.lifecycleViewModel
17 | api Libraries.lifecycleExtensions
18 | kapt Libraries.lifecycleCompiler
19 |
20 | api Libraries.room
21 | api Libraries.roomKtx
22 | kapt Libraries.roomCompiler
23 |
24 | api Libraries.okHttp
25 | api Libraries.gson
26 | api Libraries.paging
27 |
28 | api Libraries.firebaseAnalytics
29 | api Libraries.firebaseCrashlytics
30 | api Libraries.firebaseAds
31 | api Libraries.consent
32 | }
33 |
--------------------------------------------------------------------------------
/core/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/core/consumer-rules.pro
--------------------------------------------------------------------------------
/core/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/core/src/androidTest/java/me/ibrahimsn/core/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.core.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/dao/RequestDao.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.dao
2 |
3 | import androidx.paging.DataSource
4 | import androidx.room.*
5 | import me.ibrahimsn.core.domain.model.request.Request
6 |
7 | @Dao
8 | abstract class RequestDao {
9 |
10 | @Query("SELECT * from requests")
11 | abstract fun getAll(): DataSource.Factory
12 |
13 | @Insert(onConflict = OnConflictStrategy.IGNORE)
14 | abstract suspend fun insertAsync(request: Request): Long
15 |
16 | @Update
17 | abstract suspend fun update(request: Request)
18 |
19 | @Delete
20 | abstract suspend fun delete(request: Request)
21 |
22 | @Transaction
23 | open suspend fun insertOrUpdate(request: Request): Long? {
24 | val insert = insertAsync(request)
25 | if (insert != -1L) return insert
26 |
27 | update(request)
28 | return request.id
29 | }
30 |
31 | @Transaction
32 | open suspend fun delete(requests: List) {
33 | for (request in requests) {
34 | delete(request)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/dao/WebsocketDao.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.dao
2 |
3 | import androidx.paging.DataSource
4 | import androidx.room.*
5 | import me.ibrahimsn.core.domain.model.websocket.Websocket
6 |
7 | @Dao
8 | abstract class WebsocketDao {
9 |
10 | @Query("SELECT * from websockets")
11 | abstract fun getAll(): DataSource.Factory
12 |
13 | @Insert(onConflict = OnConflictStrategy.IGNORE)
14 | abstract suspend fun insertAsync(websocket: Websocket): Long
15 |
16 | @Update
17 | abstract suspend fun update(websocket: Websocket)
18 |
19 | @Delete
20 | abstract suspend fun delete(websocket: Websocket)
21 |
22 | @Transaction
23 | open suspend fun insertOrUpdate(websocket: Websocket): Long? {
24 | val insert = insertAsync(websocket)
25 | if (insert != -1L) return insert
26 |
27 | update(websocket)
28 | return websocket.id
29 | }
30 |
31 | @Transaction
32 | open suspend fun delete(websockets: List) {
33 | for (websocket in websockets) {
34 | delete(websocket)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/database/AppDatabase.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.database
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 | import androidx.room.Room
6 | import androidx.room.RoomDatabase
7 | import androidx.room.TypeConverters
8 | import me.ibrahimsn.core.data.dao.RequestDao
9 | import me.ibrahimsn.core.data.dao.WebsocketDao
10 | import me.ibrahimsn.core.domain.model.request.Request
11 | import me.ibrahimsn.core.domain.model.websocket.Websocket
12 |
13 | @Database(entities = [Request::class, Websocket::class], version = 1, exportSchema = false)
14 | @TypeConverters(Converters::class)
15 | abstract class AppDatabase : RoomDatabase() {
16 |
17 | abstract fun httpRequestDao(): RequestDao
18 | abstract fun webSocketDao(): WebsocketDao
19 |
20 | companion object {
21 |
22 | @Volatile
23 | private var INSTANCE: AppDatabase? = null
24 |
25 | fun getDatabase(context: Context): AppDatabase {
26 |
27 | val tempInstance = INSTANCE
28 |
29 | if (tempInstance != null)
30 | return tempInstance
31 |
32 | synchronized(this) {
33 | val instance = Room.databaseBuilder(context, AppDatabase::class.java, "wdevtools").build()
34 | INSTANCE = instance
35 | return instance
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/database/Converters.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.database
2 |
3 | import androidx.room.TypeConverter
4 | import me.ibrahimsn.core.data.model.RequestMethod
5 | import java.util.*
6 |
7 | class Converters {
8 |
9 | @TypeConverter
10 | fun toRequestMethod(value: Int) = enumValues()[value]
11 |
12 | @TypeConverter
13 | fun fromRequestMethod(value: RequestMethod) = value.ordinal
14 |
15 | @TypeConverter
16 | fun fromTimestamp(value: Long?): Date? {
17 | return value?.let { Date(it) }
18 | }
19 |
20 | @TypeConverter
21 | fun dateToTimestamp(date: Date?): Long? {
22 | return date?.time
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/di/DataModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.di
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import me.ibrahimsn.core.data.database.AppDatabase
6 | import me.ibrahimsn.core.data.source.DefaultPreferences
7 | import me.ibrahimsn.core.domain.source.LocalDataSource
8 | import org.koin.dsl.module
9 |
10 | private const val SECRET_KEY = "t3sT_m4sT3r_k3Y"
11 |
12 | val dataModule = module {
13 |
14 | single {
15 | provideSharedPrefs(context = get())
16 | }
17 |
18 | single {
19 | providePreferences(sharedPreferences = get())
20 | }
21 |
22 | factory {
23 | AppDatabase.getDatabase(context = get())
24 | }
25 | }
26 |
27 | private fun provideSharedPrefs(context: Context): SharedPreferences = context.getSharedPreferences(
28 | SECRET_KEY, Context.MODE_PRIVATE
29 | )
30 |
31 | fun providePreferences(sharedPreferences: SharedPreferences): LocalDataSource.Preferences =
32 | DefaultPreferences(sharedPreferences)
33 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/di/HttpModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.di
2 |
3 | import me.ibrahimsn.core.domain.source.LocalDataSource
4 | import okhttp3.OkHttpClient
5 | import org.koin.dsl.module
6 |
7 | val httpModule = module {
8 |
9 | single {
10 | provideOkHttpClient(preferences = get())
11 | }
12 | }
13 |
14 | private fun provideOkHttpClient(preferences: LocalDataSource.Preferences): OkHttpClient {
15 | return OkHttpClient
16 | .Builder()
17 | .followRedirects(preferences.isFollowRedirect())
18 | .followSslRedirects(preferences.isFollowRedirect())
19 | .build()
20 | }
21 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/di/RequestDataModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.di
2 |
3 | import me.ibrahimsn.core.data.database.AppDatabase
4 | import me.ibrahimsn.core.data.repository.RequestRepositoryImpl
5 | import me.ibrahimsn.core.domain.repository.RequestRepository
6 | import okhttp3.OkHttpClient
7 | import org.koin.dsl.module
8 |
9 | val requestDataModule = module {
10 |
11 | single {
12 | provideRequestRepository(
13 | okHttpClient = get(),
14 | appDatabase = get()
15 | )
16 | }
17 | }
18 |
19 | private fun provideRequestRepository(
20 | okHttpClient: OkHttpClient,
21 | appDatabase: AppDatabase
22 | ): RequestRepository {
23 | return RequestRepositoryImpl(
24 | okHttpClient,
25 | appDatabase
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/di/UriDataModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.di
2 |
3 | import me.ibrahimsn.core.data.repository.UriRepositoryImpl
4 | import me.ibrahimsn.core.domain.repository.UriRepository
5 | import org.koin.dsl.module
6 |
7 | val uriDataModule = module {
8 |
9 | single {
10 | provideUriRepository()
11 | }
12 | }
13 |
14 | private fun provideUriRepository(): UriRepository {
15 | return UriRepositoryImpl()
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/di/WebsocketDataModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.di
2 |
3 | import me.ibrahimsn.core.data.repository.WebsocketRepositoryImpl
4 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
5 | import okhttp3.OkHttpClient
6 | import org.koin.dsl.module
7 |
8 | val websocketDataModule = module {
9 |
10 | single {
11 | provideWebsocketRepository(
12 | okHttpClient = get(),
13 | appDatabase = get()
14 | )
15 | }
16 | }
17 |
18 | private fun provideWebsocketRepository(
19 | okHttpClient: OkHttpClient,
20 | appDatabase: me.ibrahimsn.core.data.database.AppDatabase
21 | ): WebsocketRepository {
22 | return WebsocketRepositoryImpl(okHttpClient, appDatabase)
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/model/DataHolder.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.model
2 |
3 | sealed class DataHolder {
4 |
5 | data class Success(val data: T?) : DataHolder()
6 |
7 | data class Error(val error: ErrorHolder) : DataHolder()
8 |
9 | object Loading : DataHolder()
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/model/DefaultTextWatcher.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.model
2 |
3 | import android.text.Editable
4 | import android.text.TextWatcher
5 |
6 | interface DefaultTextWatcher : TextWatcher {
7 |
8 | override fun afterTextChanged(editable: Editable?) {
9 |
10 | }
11 |
12 | override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
13 |
14 | }
15 |
16 | override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/model/ErrorHolder.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.model
2 |
3 | sealed class ErrorHolder {
4 |
5 | object InvalidParamsError: ErrorHolder()
6 | object EmptyUriError: ErrorHolder()
7 | object EmptyBodyError: ErrorHolder()
8 |
9 | object InvalidUriError: ErrorHolder()
10 | object SocketClosedError: ErrorHolder()
11 |
12 | data class NetworkError(val cause: Throwable): ErrorHolder()
13 | data class SocketError(val cause: Throwable): ErrorHolder()
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/model/RequestMethod.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.model
2 |
3 | import androidx.annotation.ColorRes
4 | import androidx.annotation.DrawableRes
5 | import me.ibrahimsn.core.R
6 |
7 | enum class RequestMethod(
8 | val hasBody: Boolean,
9 | @ColorRes val colorRes: Int,
10 | @DrawableRes val backgroundRes: Int,
11 | val shortName: String
12 | ) {
13 |
14 | GET(
15 | false,
16 | R.color.colorGet,
17 | R.drawable.ic_background_method_get,
18 | "GET"
19 | ),
20 |
21 | POST(
22 | true,
23 | R.color.colorPost,
24 | R.drawable.ic_background_method_post,
25 | "PST"
26 | ),
27 |
28 | PUT(
29 | true,
30 | R.color.colorPut,
31 | R.drawable.ic_background_method_put,
32 | "PUT"
33 | ),
34 |
35 | DEL(
36 | true,
37 | R.color.colorDelete,
38 | R.drawable.ic_background_method_delete,
39 | "DEL"
40 | ),
41 |
42 | PATCH(
43 | true,
44 | R.color.colorPatch,
45 | R.drawable.ic_background_method_patch,
46 | "PCH"
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/repository/RequestRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.repository
2 |
3 | import androidx.paging.DataSource
4 | import me.ibrahimsn.core.data.database.AppDatabase
5 | import me.ibrahimsn.core.data.model.DataHolder
6 | import me.ibrahimsn.core.data.model.ErrorHolder
7 | import me.ibrahimsn.core.data.model.RequestMethod
8 | import me.ibrahimsn.core.domain.model.param.Param
9 | import me.ibrahimsn.core.domain.model.request.Request
10 | import me.ibrahimsn.core.domain.model.request.RequestResponse
11 | import me.ibrahimsn.core.domain.repository.RequestRepository
12 | import okhttp3.*
13 | import java.io.IOException
14 | import kotlin.coroutines.resume
15 | import kotlin.coroutines.suspendCoroutine
16 |
17 | class RequestRepositoryImpl (
18 | private val okHttpClient: OkHttpClient,
19 | private val appDatabase: AppDatabase
20 | ) : RequestRepository {
21 |
22 | override suspend fun makeRequest(
23 | uri: String,
24 | method: RequestMethod,
25 | headerParams: List?,
26 | bodyParams: List?
27 | ): DataHolder {
28 |
29 | val requestBuilder = okhttp3.Request.Builder()
30 | .url(uri)
31 | var requestHeaders: Headers? = null
32 | var requestBody: RequestBody? = null
33 |
34 | headerParams?.filter {
35 | it.isActive && it.key.isNotEmpty() && it.value.isNotEmpty()
36 | }?.let { params ->
37 | if (params.isNotEmpty()) {
38 | requestHeaders = Headers.Builder().apply {
39 | params.forEach { param ->
40 | add(param.key, param.value)
41 | }
42 | }.build()
43 | }
44 | }
45 |
46 | requestHeaders?.let {
47 | requestBuilder.headers(it)
48 | }
49 |
50 | bodyParams?.filter {
51 | it.isActive && it.key.isNotEmpty() && it.value.isNotEmpty()
52 | }?.let { params ->
53 | if (params.isNotEmpty()) {
54 | requestBody = MultipartBody.Builder().setType(MultipartBody.FORM).apply {
55 | params.forEach { param ->
56 | addFormDataPart(param.key, param.value)
57 | }
58 | }.build()
59 | }
60 | }
61 |
62 | requestBuilder.method(method.name, requestBody)
63 |
64 | return suspendCoroutine { continuation ->
65 | okHttpClient.newCall(requestBuilder.build()).enqueue(object: Callback {
66 | override fun onResponse(call: Call, response: Response) {
67 | continuation.resume(
68 | DataHolder.Success(
69 | RequestResponse(
70 | status = response.isSuccessful,
71 | code = response.code,
72 | body = response.body?.string()
73 | )
74 | )
75 | )
76 | }
77 |
78 | override fun onFailure(call: Call, e: IOException) {
79 | continuation.resume(
80 | DataHolder.Error(ErrorHolder.NetworkError(e))
81 | )
82 | }
83 | })
84 | }
85 | }
86 |
87 | override fun getAllRequests(): DataSource.Factory {
88 | return appDatabase.httpRequestDao().getAll()
89 | }
90 |
91 | override suspend fun saveOrUpdateRequest(request: Request): DataHolder {
92 | return DataHolder.Success(appDatabase.httpRequestDao().insertOrUpdate(request))
93 | }
94 |
95 | override suspend fun deleteRequests(requests: List): DataHolder {
96 | return DataHolder.Success(appDatabase.httpRequestDao().delete(requests))
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/repository/UriRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.repository
2 |
3 | import android.net.Uri
4 | import me.ibrahimsn.core.data.model.DataHolder
5 | import me.ibrahimsn.core.data.model.ErrorHolder
6 | import me.ibrahimsn.core.domain.model.param.Param
7 | import me.ibrahimsn.core.domain.repository.UriRepository
8 |
9 | class UriRepositoryImpl : UriRepository {
10 |
11 | override suspend fun parseUriQueryParams(uri: String): DataHolder?> {
12 | val parsed = Uri.parse(uri)
13 | val params = mutableListOf()
14 |
15 | if (parsed.isOpaque) {
16 | return DataHolder.Error(ErrorHolder.InvalidUriError)
17 | }
18 |
19 | for (param in parsed.queryParameterNames) {
20 | parsed.getQueryParameter(param)?.let {
21 | params.add(Param(true, param, it))
22 | }
23 | }
24 |
25 | return DataHolder.Success(params)
26 | }
27 |
28 | override suspend fun generateUri(uri: String, queryParams: List): DataHolder {
29 | val builder = Uri.parse(uri)
30 | .buildUpon()
31 | .clearQuery()
32 |
33 | for (param in queryParams.filter {
34 | it.isActive && it.key.isNotEmpty() && it.value.isNotEmpty()
35 | }) {
36 | builder.appendQueryParameter(param.key, param.value)
37 | }
38 |
39 | return DataHolder.Success(builder.build())
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/repository/WebsocketRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.repository
2 |
3 | import androidx.paging.DataSource
4 | import kotlinx.coroutines.channels.Channel
5 | import me.ibrahimsn.core.data.database.AppDatabase
6 | import me.ibrahimsn.core.data.model.DataHolder
7 | import me.ibrahimsn.core.data.model.ErrorHolder
8 | import me.ibrahimsn.core.domain.model.param.Param
9 | import me.ibrahimsn.core.domain.model.websocket.Websocket
10 | import me.ibrahimsn.core.domain.model.websocket.WebsocketEvent
11 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
12 | import okhttp3.*
13 |
14 | class WebsocketRepositoryImpl (
15 | private val okHttpClient: OkHttpClient,
16 | private val appDatabase: AppDatabase
17 | ) : WebsocketRepository {
18 |
19 | override suspend fun connectWebsocket(
20 | channel: Channel,
21 | uri: String,
22 | headerParams: List?
23 | ) {
24 | val requestBuilder = Request.Builder().url(uri)
25 | var requestHeaders: Headers? = null
26 |
27 | headerParams?.filter {
28 | it.isActive && it.key.isNotEmpty() && it.value.isNotEmpty()
29 | }?.let { params ->
30 | if (params.isNotEmpty()) {
31 | requestHeaders = Headers.Builder().apply {
32 | params.forEach { param ->
33 | add(param.key, param.value)
34 | }
35 | }.build()
36 | }
37 | }
38 |
39 | requestHeaders?.let {
40 | requestBuilder.headers(it)
41 | }
42 |
43 | okHttpClient.newWebSocket(requestBuilder.build(), object: WebSocketListener() {
44 | override fun onOpen(webSocket: WebSocket, response: Response) {
45 | super.onOpen(webSocket, response)
46 | channel.offer(WebsocketEvent.OnOpen(webSocket))
47 | }
48 |
49 | override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
50 | super.onClosed(webSocket, code, reason)
51 | channel.offer(WebsocketEvent.OnClosed)
52 | }
53 |
54 | override fun onMessage(webSocket: WebSocket, text: String) {
55 | super.onMessage(webSocket, text)
56 | channel.offer(WebsocketEvent.OnMessage(text))
57 | }
58 |
59 | override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
60 | super.onFailure(webSocket, t, response)
61 | channel.offer(
62 | WebsocketEvent.OnFailure(
63 | ErrorHolder.SocketError(t)
64 | )
65 | )
66 | }
67 | })
68 | }
69 |
70 | override fun getAllWebsockets(): DataSource.Factory {
71 | return appDatabase.webSocketDao().getAll()
72 | }
73 |
74 | override suspend fun saveOrUpdateWebsocket(websocket: Websocket): DataHolder {
75 | return DataHolder.Success(appDatabase.webSocketDao().insertOrUpdate(websocket))
76 | }
77 |
78 | override suspend fun deleteWebsockets(websocket: List): DataHolder {
79 | return DataHolder.Success(appDatabase.webSocketDao().delete(websocket))
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/data/source/DefaultPreferences.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.data.source
2 |
3 | import android.content.SharedPreferences
4 | import me.ibrahimsn.core.domain.source.LocalDataSource
5 | import me.ibrahimsn.core.domain.source.LocalDataSource.Preferences.Companion.KEY_CONSENT_STATUS
6 | import me.ibrahimsn.core.domain.source.LocalDataSource.Preferences.Companion.KEY_FOLLOW_REDIRECT
7 | import me.ibrahimsn.core.domain.source.LocalDataSource.Preferences.Companion.KEY_HAS_CONSENT_STATUS
8 |
9 | class DefaultPreferences constructor(override val sharedPreferences: SharedPreferences)
10 | : LocalDataSource.Preferences {
11 |
12 | override fun isFollowRedirect(): Boolean =
13 | sharedPreferences.getBoolean(KEY_FOLLOW_REDIRECT, true)
14 |
15 | override fun getConsentStatus(): Boolean =
16 | sharedPreferences.getBoolean(KEY_CONSENT_STATUS, true)
17 |
18 | override fun hasConsentStatus(): Boolean =
19 | sharedPreferences.getBoolean(KEY_HAS_CONSENT_STATUS, false)
20 |
21 | override fun setConsentStatus(consentStatus: Boolean) =
22 | sharedPreferences.edit()
23 | .putBoolean(KEY_CONSENT_STATUS, consentStatus)
24 | .putBoolean(KEY_HAS_CONSENT_STATUS, true)
25 | .apply()
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/Constants.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain
2 |
3 | object Constants {
4 |
5 | const val DEFAULT_REQUEST_URI = "https://google.com"
6 | const val DEFAULT_WEBSOCKET_URI = "wss://echo.websocket.org"
7 | }
8 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/di/RequestDomainModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.di
2 |
3 | import me.ibrahimsn.core.domain.interactor.Interactor
4 | import me.ibrahimsn.core.domain.interactor.request.DeleteRequestsInteractor
5 | import me.ibrahimsn.core.domain.interactor.request.GetAllRequestsInteractor
6 | import me.ibrahimsn.core.domain.interactor.request.MakeRequestInteractor
7 | import me.ibrahimsn.core.domain.interactor.request.SaveOrUpdateRequestInteractor
8 | import me.ibrahimsn.core.domain.model.request.Request
9 | import me.ibrahimsn.core.domain.model.request.RequestResponse
10 | import me.ibrahimsn.core.domain.repository.RequestRepository
11 | import org.koin.core.qualifier.named
12 | import org.koin.dsl.module
13 |
14 | val requestDomainModule = module {
15 |
16 | factory (named(GetAllRequestsInteractor.NAME)) {
17 | provideGetAllRequestsInteractor(
18 | requestRepository = get()
19 | )
20 | }
21 |
22 | factory (named(MakeRequestInteractor.NAME)) {
23 | provideMakeRequestInteractor(
24 | requestRepository = get()
25 | )
26 | }
27 |
28 | factory (named(SaveOrUpdateRequestInteractor.NAME)) {
29 | provideSaveOrUpdateRequestInteractor(
30 | requestRepository = get()
31 | )
32 | }
33 |
34 | factory (named(DeleteRequestsInteractor.NAME)) {
35 | provideDeleteRequestsInteractor(
36 | requestRepository = get()
37 | )
38 | }
39 | }
40 |
41 | private fun provideGetAllRequestsInteractor(requestRepository: RequestRepository)
42 | : Interactor.PagingInteractor {
43 | return GetAllRequestsInteractor(requestRepository)
44 | }
45 |
46 | private fun provideMakeRequestInteractor(requestRepository: RequestRepository)
47 | : Interactor.RequestInteractor {
48 | return MakeRequestInteractor(requestRepository)
49 | }
50 |
51 | private fun provideSaveOrUpdateRequestInteractor(requestRepository: RequestRepository)
52 | : Interactor.RequestInteractor {
53 | return SaveOrUpdateRequestInteractor(requestRepository)
54 | }
55 |
56 | private fun provideDeleteRequestsInteractor(requestRepository: RequestRepository)
57 | : Interactor.RequestInteractor {
58 | return DeleteRequestsInteractor(requestRepository)
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/di/UriDomainModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.di
2 |
3 | import android.net.Uri
4 | import me.ibrahimsn.core.domain.interactor.Interactor
5 | import me.ibrahimsn.core.domain.interactor.uri.GenerateUriInteractor
6 | import me.ibrahimsn.core.domain.interactor.uri.ParseUriParamsInteractor
7 | import me.ibrahimsn.core.domain.model.param.Param
8 | import me.ibrahimsn.core.domain.repository.UriRepository
9 | import org.koin.core.qualifier.named
10 | import org.koin.dsl.module
11 |
12 | val uriDomainModule = module {
13 |
14 | factory(named(GenerateUriInteractor.NAME)) {
15 | provideGenerateUriInteractor(uriRepository = get())
16 | }
17 |
18 | factory(named(ParseUriParamsInteractor.NAME)) {
19 | provideParseUriParamsInteractor(uriRepository = get())
20 | }
21 | }
22 |
23 | private fun provideGenerateUriInteractor(uriRepository: UriRepository)
24 | : Interactor.RequestInteractor {
25 | return GenerateUriInteractor(uriRepository)
26 | }
27 |
28 | private fun provideParseUriParamsInteractor(uriRepository: UriRepository)
29 | : Interactor.RequestInteractor?> {
30 | return ParseUriParamsInteractor(uriRepository)
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/di/WebsocketDomainModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.di
2 |
3 | import me.ibrahimsn.core.domain.interactor.Interactor
4 | import me.ibrahimsn.core.domain.interactor.websocket.ConnectWebsocketInteractor
5 | import me.ibrahimsn.core.domain.interactor.websocket.DeleteWebsocketsInteractor
6 | import me.ibrahimsn.core.domain.interactor.websocket.GetAllWebsocketsInteractor
7 | import me.ibrahimsn.core.domain.interactor.websocket.SaveOrUpdateWebsocketInteractor
8 | import me.ibrahimsn.core.domain.model.websocket.Websocket
9 | import me.ibrahimsn.core.domain.model.websocket.WebsocketEvent
10 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
11 | import org.koin.core.qualifier.named
12 | import org.koin.dsl.module
13 |
14 | val websocketDomainModule = module {
15 |
16 | factory (named(ConnectWebsocketInteractor.NAME)) {
17 | provideConnectWebsocketInteractor(
18 | websocketRepository = get()
19 | )
20 | }
21 |
22 | factory (named(GetAllWebsocketsInteractor.NAME)) {
23 | provideGetAllWebsocketsInteractor(
24 | websocketRepository = get()
25 | )
26 | }
27 |
28 | factory (named(SaveOrUpdateWebsocketInteractor.NAME)) {
29 | provideSaveOrUpdateRequestInteractor(
30 | websocketRepository = get()
31 | )
32 | }
33 |
34 | factory (named(DeleteWebsocketsInteractor.NAME)) {
35 | provideDeleteRequestsInteractor(
36 | websocketRepository = get()
37 | )
38 | }
39 | }
40 |
41 | private fun provideConnectWebsocketInteractor(websocketRepository: WebsocketRepository)
42 | : Interactor.ObserveInteractor{
43 | return ConnectWebsocketInteractor(websocketRepository)
44 | }
45 |
46 | private fun provideGetAllWebsocketsInteractor(websocketRepository: WebsocketRepository)
47 | : Interactor.PagingInteractor {
48 | return GetAllWebsocketsInteractor(websocketRepository)
49 | }
50 |
51 | private fun provideSaveOrUpdateRequestInteractor(websocketRepository: WebsocketRepository)
52 | : Interactor.RequestInteractor {
53 | return SaveOrUpdateWebsocketInteractor(websocketRepository)
54 | }
55 |
56 | private fun provideDeleteRequestsInteractor(websocketRepository: WebsocketRepository)
57 | : Interactor.RequestInteractor {
58 | return DeleteWebsocketsInteractor(websocketRepository)
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/Interactor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor
2 |
3 | import androidx.paging.DataSource
4 | import kotlinx.coroutines.channels.Channel
5 | import me.ibrahimsn.core.data.model.DataHolder
6 |
7 | interface Interactor {
8 |
9 | interface RequestInteractor : Interactor {
10 | suspend fun invoke(params: P?): DataHolder
11 | }
12 |
13 | interface RetrieveInteractor : Interactor {
14 | suspend fun invoke(): DataHolder
15 | }
16 |
17 | interface ObserveInteractor: Interactor {
18 | suspend fun invoke(channel: Channel, params: P?)
19 | }
20 |
21 | interface PagingInteractor: Interactor {
22 | fun invoke(): DataSource.Factory
23 | }
24 |
25 | abstract class Params {
26 | // marker class
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/request/DeleteRequestsInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.request
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.request.Request
7 | import me.ibrahimsn.core.domain.repository.RequestRepository
8 |
9 | class DeleteRequestsInteractor (private val repository: RequestRepository)
10 | : Interactor.RequestInteractor {
11 |
12 | override suspend fun invoke(params: Params?): DataHolder {
13 |
14 | if (params == null)
15 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
16 |
17 | if (params.requests == null)
18 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
19 |
20 | return repository.deleteRequests(params.requests)
21 | }
22 |
23 | class Params(
24 | val requests: List?
25 | ) : Interactor.Params()
26 |
27 | companion object {
28 | const val NAME = "DeleteRequestInteractor"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/request/GetAllRequestsInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.request
2 |
3 | import androidx.paging.DataSource
4 | import me.ibrahimsn.core.domain.interactor.Interactor
5 | import me.ibrahimsn.core.domain.model.request.Request
6 | import me.ibrahimsn.core.domain.repository.RequestRepository
7 |
8 | class GetAllRequestsInteractor (private val repository: RequestRepository)
9 | : Interactor.PagingInteractor {
10 |
11 | override fun invoke(): DataSource.Factory {
12 | return repository.getAllRequests()
13 | }
14 |
15 | companion object {
16 | const val NAME = "GetAllRequestsInteractor"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/request/MakeRequestInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.request
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.data.model.RequestMethod
6 | import me.ibrahimsn.core.domain.interactor.Interactor
7 | import me.ibrahimsn.core.domain.model.param.Param
8 | import me.ibrahimsn.core.domain.model.request.RequestResponse
9 | import me.ibrahimsn.core.domain.repository.RequestRepository
10 | import me.ibrahimsn.core.presentation.extension.isValidUri
11 |
12 | class MakeRequestInteractor (private val repository: RequestRepository)
13 | : Interactor.RequestInteractor {
14 |
15 | override suspend fun invoke(params: Params?): DataHolder {
16 |
17 | if (params == null)
18 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
19 |
20 | if (params.uri.isNullOrEmpty())
21 | return DataHolder.Error(ErrorHolder.EmptyUriError)
22 |
23 | if (!params.uri.isValidUri())
24 | return DataHolder.Error(ErrorHolder.InvalidUriError)
25 |
26 | if (params.method == null)
27 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
28 |
29 | if (params.method.hasBody && params.bodyParams.isNullOrEmpty())
30 | return DataHolder.Error(ErrorHolder.EmptyBodyError)
31 |
32 | return repository.makeRequest(
33 | uri = params.uri,
34 | method = params.method,
35 | headerParams = params.headerParams,
36 | bodyParams = params.bodyParams
37 | )
38 | }
39 |
40 | class Params(
41 | val uri: String?,
42 | val method: RequestMethod?,
43 | val headerParams: List?,
44 | val bodyParams: List?
45 | ) : Interactor.Params()
46 |
47 | companion object {
48 | const val NAME = "MakeRequestInteractor"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/request/SaveOrUpdateRequestInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.request
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.request.Request
7 | import me.ibrahimsn.core.domain.repository.RequestRepository
8 |
9 | class SaveOrUpdateRequestInteractor (private val repository: RequestRepository)
10 | : Interactor.RequestInteractor {
11 |
12 | override suspend fun invoke(params: Params?): DataHolder {
13 |
14 | if (params == null)
15 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
16 |
17 | if (params.request == null)
18 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
19 |
20 | return repository.saveOrUpdateRequest(params.request)
21 | }
22 |
23 | class Params(
24 | val request: Request?
25 | ) : Interactor.Params()
26 |
27 | companion object {
28 | const val NAME = "UpdateRequestInteractor"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/uri/GenerateUriInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.uri
2 |
3 | import android.net.Uri
4 | import me.ibrahimsn.core.data.model.DataHolder
5 | import me.ibrahimsn.core.data.model.ErrorHolder
6 | import me.ibrahimsn.core.domain.interactor.Interactor
7 | import me.ibrahimsn.core.domain.model.param.Param
8 | import me.ibrahimsn.core.domain.repository.UriRepository
9 |
10 | class GenerateUriInteractor (private val uriRepository: UriRepository)
11 | : Interactor.RequestInteractor {
12 |
13 | override suspend fun invoke(params: Params?): DataHolder {
14 |
15 | if (params == null)
16 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
17 |
18 | return uriRepository.generateUri(params.uri, params.queryParams)
19 | }
20 |
21 | class Params(val uri: String, val queryParams: List) : Interactor.Params()
22 |
23 | companion object {
24 | const val NAME = "GenerateUriInteractor"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/uri/ParseUriParamsInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.uri
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.param.Param
7 | import me.ibrahimsn.core.domain.repository.UriRepository
8 |
9 | class ParseUriParamsInteractor (private val uriRepository: UriRepository)
10 | : Interactor.RequestInteractor?> {
11 |
12 | override suspend fun invoke(params: Params?): DataHolder?> {
13 |
14 | if (params == null)
15 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
16 |
17 | if (params.uri == null)
18 | return DataHolder.Error(ErrorHolder.EmptyUriError)
19 |
20 | return uriRepository.parseUriQueryParams(params.uri)
21 | }
22 |
23 | class Params(val uri: String?) : Interactor.Params()
24 |
25 | companion object {
26 | const val NAME = "ParseUriParamsInteractor"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/websocket/ConnectWebsocketInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.websocket
2 |
3 | import kotlinx.coroutines.channels.Channel
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.param.Param
7 | import me.ibrahimsn.core.domain.model.websocket.WebsocketEvent
8 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
9 | import me.ibrahimsn.core.presentation.extension.isValidUri
10 |
11 | class ConnectWebsocketInteractor (private val repository: WebsocketRepository)
12 | : Interactor.ObserveInteractor {
13 |
14 | override suspend fun invoke(channel: Channel, params: Params?) {
15 |
16 | if (params == null) {
17 | channel.offer(WebsocketEvent.OnFailure(ErrorHolder.InvalidParamsError))
18 | return
19 | }
20 |
21 | if (params.uri.isNullOrEmpty()) {
22 | channel.offer(WebsocketEvent.OnFailure(ErrorHolder.EmptyUriError))
23 | return
24 | }
25 |
26 | if (!params.uri.isValidUri()) {
27 | channel.offer(WebsocketEvent.OnFailure(ErrorHolder.InvalidUriError))
28 | return
29 | }
30 |
31 | repository.connectWebsocket(
32 | channel = channel,
33 | uri = params.uri,
34 | headerParams = params.headerParams
35 | )
36 | }
37 |
38 | class Params(
39 | val uri: String?,
40 | val headerParams: List?
41 | ) : Interactor.Params()
42 |
43 | companion object {
44 | const val NAME = "ConnectWebsocketInteractor"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/websocket/DeleteWebsocketsInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.websocket
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.websocket.Websocket
7 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
8 |
9 | class DeleteWebsocketsInteractor (private val repository: WebsocketRepository)
10 | : Interactor.RequestInteractor {
11 |
12 | override suspend fun invoke(params: Params?): DataHolder {
13 |
14 | if (params == null)
15 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
16 |
17 | if (params.websockets == null)
18 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
19 |
20 | return repository.deleteWebsockets(params.websockets)
21 | }
22 |
23 | class Params(
24 | val websockets: List?
25 | ) : Interactor.Params()
26 |
27 | companion object {
28 | const val NAME = "DeleteWebsocketsInteractor"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/websocket/GetAllWebsocketsInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.websocket
2 |
3 | import androidx.paging.DataSource
4 | import me.ibrahimsn.core.domain.interactor.Interactor
5 | import me.ibrahimsn.core.domain.model.websocket.Websocket
6 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
7 |
8 | class GetAllWebsocketsInteractor (private val repository: WebsocketRepository)
9 | : Interactor.PagingInteractor {
10 |
11 | override fun invoke(): DataSource.Factory {
12 | return repository.getAllWebsockets()
13 | }
14 |
15 | companion object {
16 | const val NAME = "GetAllWebsocketsInteractor"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/interactor/websocket/SaveOrUpdateWebsocketInteractor.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.interactor.websocket
2 |
3 | import me.ibrahimsn.core.data.model.DataHolder
4 | import me.ibrahimsn.core.data.model.ErrorHolder
5 | import me.ibrahimsn.core.domain.interactor.Interactor
6 | import me.ibrahimsn.core.domain.model.websocket.Websocket
7 | import me.ibrahimsn.core.domain.repository.WebsocketRepository
8 |
9 | class SaveOrUpdateWebsocketInteractor (private val repository: WebsocketRepository)
10 | : Interactor.RequestInteractor {
11 |
12 | override suspend fun invoke(params: Params?): DataHolder {
13 |
14 | if (params == null)
15 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
16 |
17 | if (params.websocket == null)
18 | return DataHolder.Error(ErrorHolder.InvalidParamsError)
19 |
20 | return repository.saveOrUpdateWebsocket(params.websocket)
21 | }
22 |
23 | class Params(
24 | val websocket: Websocket?
25 | ) : Interactor.Params()
26 |
27 | companion object {
28 | const val NAME = "UpdateWebsocketInteractor"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/model/param/Param.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.model.param
2 |
3 | import android.os.Parcelable
4 | import kotlinx.android.parcel.Parcelize
5 |
6 | @Parcelize
7 | data class Param(
8 | var isActive: Boolean,
9 | var key: String,
10 | var value: String
11 | ): Parcelable {
12 |
13 | companion object {
14 |
15 | fun newInstance(): Param {
16 | return Param(true, "", "")
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/model/request/Request.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.model.request
2 |
3 | import android.os.Parcelable
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 | import kotlinx.android.parcel.Parcelize
7 | import me.ibrahimsn.core.data.model.RequestMethod
8 | import java.util.*
9 |
10 | @Parcelize
11 | @Entity(tableName = "requests")
12 | data class Request(
13 | var uri: String,
14 | var headerParams: String,
15 | var bodyParams: String,
16 | var method: RequestMethod,
17 | var createdAt: Date,
18 | @PrimaryKey(autoGenerate = true) var id: Long? = null
19 | ): Parcelable {
20 |
21 | companion object {
22 |
23 | fun newInstance(uri: String): Request {
24 | return Request(uri, "", "", RequestMethod.GET, Date())
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/model/request/RequestResponse.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.model.request
2 |
3 | data class RequestResponse(
4 | val status: Boolean,
5 | val code: Int,
6 | val body: String?
7 | )
8 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/model/websocket/Websocket.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.model.websocket
2 |
3 | import android.os.Parcelable
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 | import kotlinx.android.parcel.Parcelize
7 | import java.util.*
8 |
9 | @Parcelize
10 | @Entity(tableName = "websockets")
11 | data class Websocket(
12 | var uri: String,
13 | var headerParams: String,
14 | var createdAt: Date,
15 | @PrimaryKey(autoGenerate = true) var id: Long? = null
16 | ): Parcelable {
17 |
18 | companion object {
19 |
20 | fun newInstance(uri: String): Websocket {
21 | return Websocket(uri, "", Date())
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/model/websocket/WebsocketEvent.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.model.websocket
2 |
3 | import me.ibrahimsn.core.data.model.ErrorHolder
4 | import okhttp3.WebSocket
5 |
6 | sealed class WebsocketEvent {
7 |
8 | object OnClosed: WebsocketEvent()
9 | data class OnOpen(val websocket: WebSocket): WebsocketEvent()
10 | data class OnMessage(val text: String): WebsocketEvent()
11 | data class OnFailure(val error: ErrorHolder): WebsocketEvent()
12 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/repository/RequestRepository.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.repository
2 |
3 | import androidx.paging.DataSource
4 | import me.ibrahimsn.core.data.model.DataHolder
5 | import me.ibrahimsn.core.data.model.RequestMethod
6 | import me.ibrahimsn.core.domain.model.param.Param
7 | import me.ibrahimsn.core.domain.model.request.Request
8 | import me.ibrahimsn.core.domain.model.request.RequestResponse
9 |
10 | interface RequestRepository {
11 |
12 | suspend fun makeRequest(
13 | uri: String,
14 | method: RequestMethod,
15 | headerParams: List?,
16 | bodyParams: List?
17 | ): DataHolder
18 |
19 | fun getAllRequests(): DataSource.Factory
20 |
21 | suspend fun saveOrUpdateRequest(request: Request): DataHolder
22 |
23 | suspend fun deleteRequests(requests: List): DataHolder
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/repository/UriRepository.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.repository
2 |
3 | import android.net.Uri
4 | import me.ibrahimsn.core.data.model.DataHolder
5 | import me.ibrahimsn.core.domain.model.param.Param
6 |
7 | interface UriRepository {
8 |
9 | suspend fun parseUriQueryParams(uri: String): DataHolder?>
10 |
11 | suspend fun generateUri(uri: String, queryParams: List): DataHolder
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/repository/WebsocketRepository.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.repository
2 |
3 | import androidx.paging.DataSource
4 | import kotlinx.coroutines.channels.Channel
5 | import me.ibrahimsn.core.data.model.DataHolder
6 | import me.ibrahimsn.core.domain.model.param.Param
7 | import me.ibrahimsn.core.domain.model.websocket.Websocket
8 | import me.ibrahimsn.core.domain.model.websocket.WebsocketEvent
9 |
10 | interface WebsocketRepository {
11 |
12 | suspend fun connectWebsocket(
13 | channel: Channel,
14 | uri: String,
15 | headerParams: List?
16 | )
17 |
18 | fun getAllWebsockets(): DataSource.Factory
19 |
20 | suspend fun saveOrUpdateWebsocket(websocket: Websocket): DataHolder
21 |
22 | suspend fun deleteWebsockets(websocket: List): DataHolder
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/domain/source/LocalDataSource.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.domain.source
2 |
3 | import android.content.SharedPreferences
4 |
5 | interface LocalDataSource {
6 |
7 | interface Preferences : LocalDataSource {
8 |
9 | val sharedPreferences: SharedPreferences
10 |
11 | fun isFollowRedirect(): Boolean
12 |
13 | fun getConsentStatus(): Boolean
14 |
15 | fun hasConsentStatus(): Boolean
16 |
17 | fun setConsentStatus(consentStatus: Boolean)
18 |
19 | companion object {
20 | const val KEY_FOLLOW_REDIRECT = "key_follow_redirect"
21 | const val KEY_CONSENT_STATUS = "key_consent_status"
22 | const val KEY_HAS_CONSENT_STATUS = "key_has_consent_status"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/Constants.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation
2 |
3 | object Constants {
4 |
5 | const val PUBLISHER_ID = ""
6 | const val BANNER_AD_UNIT_ID = ""
7 | const val ADMOB_TEST_DEVICE = ""
8 | const val PRIVACY_URL = "https://ibrahimsn98.github.io/web/webdevtools-privacy-policy"
9 | }
10 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import android.os.Bundle
4 | import android.view.Menu
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MenuRes
7 | import androidx.annotation.StringRes
8 | import androidx.appcompat.app.AppCompatActivity
9 | import androidx.appcompat.widget.Toolbar
10 |
11 | abstract class BaseActivity : AppCompatActivity() {
12 |
13 | @LayoutRes
14 | protected abstract fun layoutRes(): Int
15 |
16 | @MenuRes
17 | protected open fun menuRes(): Int? = null
18 |
19 | @StringRes
20 | protected open fun titleRes(): Int? = null
21 |
22 | protected open fun toolbar(): Toolbar? = null
23 |
24 | protected open fun showBackButton(): Boolean = false
25 |
26 | abstract fun initView()
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | setContentView(layoutRes())
31 |
32 | toolbar()?.let { setSupportActionBar(it) }
33 | titleRes()?.let { setTitle(it) }
34 |
35 | supportActionBar?.setHomeButtonEnabled(showBackButton())
36 | supportActionBar?.setDisplayHomeAsUpEnabled(showBackButton())
37 |
38 | initView()
39 | }
40 |
41 | override fun onCreateOptionsMenu(menu: Menu?): Boolean {
42 | menuRes()?.let {
43 | menuInflater.inflate(it, menu)
44 | }
45 | return super.onCreateOptionsMenu(menu)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BaseAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import androidx.recyclerview.widget.DiffUtil
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 | abstract class BaseAdapter : RecyclerView.Adapter() where VH: BaseViewHolder {
7 |
8 | protected val items = mutableListOf()
9 |
10 | abstract fun areItemsTheSame(oldItem: T, newItem: T): Boolean
11 |
12 | abstract fun areContentsTheSame(oldItem: T, newItem: T): Boolean
13 |
14 | override fun onBindViewHolder(holder: VH, position: Int) {
15 | holder.bind(items[position])
16 | }
17 |
18 | override fun getItemCount() = items.size
19 |
20 | class DiffCallback : DiffUtil.ItemCallback() {
21 |
22 | override fun areItemsTheSame(oldItem: T, newItem: T): Boolean
23 | = areItemsTheSame(oldItem, newItem)
24 |
25 | override fun areContentsTheSame(oldItem: T, newItem: T): Boolean
26 | = areContentsTheSame(oldItem, newItem)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.annotation.LayoutRes
8 | import androidx.fragment.app.Fragment
9 |
10 | abstract class BaseFragment : Fragment() {
11 |
12 | @LayoutRes
13 | protected abstract fun layoutRes(): Int
14 |
15 | abstract fun initView()
16 |
17 | abstract fun observeData()
18 |
19 | open fun initData() {
20 |
21 | }
22 |
23 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
24 | return layoutInflater.inflate(layoutRes(), container, false)
25 | }
26 |
27 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
28 | super.onViewCreated(view, savedInstanceState)
29 | initData()
30 | initView()
31 | observeData()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BasePagedAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import androidx.paging.PagedListAdapter
4 | import androidx.recyclerview.widget.DiffUtil
5 |
6 | abstract class BasePagedAdapter(diffCallback: DiffUtil.ItemCallback)
7 | : PagedListAdapter(diffCallback) where VH: BaseViewHolder {
8 |
9 | private val _selectedItems = mutableMapOf()
10 | val selectedItems: Map get() = _selectedItems
11 |
12 | abstract fun onClearSelectedItems()
13 |
14 | fun isSelectedItem(pos: Int): Boolean = _selectedItems.containsKey(pos)
15 |
16 | override fun onBindViewHolder(holder: VH, position: Int) {
17 | holder.bind(getItem(position))
18 | }
19 |
20 | fun deselectAll() {
21 | val iterator = _selectedItems.iterator()
22 | while (iterator.hasNext()) {
23 | val selectedItem = iterator.next()
24 | if (_selectedItems.containsKey(selectedItem.key)) {
25 | notifyItemChanged(selectedItem.key)
26 | iterator.remove()
27 | }
28 | }
29 | }
30 |
31 | fun deselectItem(pos: Int) {
32 | _selectedItems.remove(pos)
33 | notifyItemChanged(pos)
34 | }
35 |
36 | fun toggleSelection(request: T?, pos: Int) {
37 | if (_selectedItems.containsKey(pos)) {
38 | _selectedItems.remove(pos)
39 | if (_selectedItems.isEmpty()) {
40 | onClearSelectedItems()
41 | }
42 | } else {
43 | request?.let {
44 | _selectedItems[pos] = it
45 | }
46 | }
47 |
48 | notifyItemChanged(pos)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BaseViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 | abstract class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
7 |
8 | protected var boundItem: T? = null
9 |
10 | open fun bind(item: T?) {
11 | boundItem = item
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.base
2 |
3 | import androidx.lifecycle.ViewModel
4 |
5 | abstract class BaseViewModel : ViewModel()
6 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/AdExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import android.os.Bundle
4 | import com.google.ads.mediation.admob.AdMobAdapter
5 | import com.google.android.gms.ads.AdRequest
6 |
7 | fun AdRequest.Builder.setNonPersonalized() {
8 | this.addNetworkExtrasBundle(AdMobAdapter::class.java, Bundle().apply {
9 | putString("npa", "1")
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/CoroutineScopeExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import kotlinx.coroutines.CoroutineScope
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.launch
6 |
7 | fun CoroutineScope.io(codeBlock: suspend CoroutineScope.() -> Unit) {
8 | launch(Dispatchers.IO) {
9 | codeBlock()
10 | }
11 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/DateExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import java.text.SimpleDateFormat
4 | import java.util.*
5 |
6 | fun Date?.toDateString(): String? {
7 | this?.let {
8 | return SimpleDateFormat("dd MMM hh:mm", Locale.getDefault()).format(this)
9 | }
10 | return null
11 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/GsonExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import com.google.gson.Gson
4 |
5 | fun Any?.toJson(): String? {
6 | return Gson().toJson(this)
7 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/LifecycleExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import android.widget.Toast
4 | import androidx.annotation.StringRes
5 | import me.ibrahimsn.core.presentation.base.BaseFragment
6 |
7 | fun BaseFragment.showToast(@StringRes textRes: Int) {
8 | this.activity?.let {
9 | Toast.makeText(it, textRes, Toast.LENGTH_SHORT).show()
10 | }
11 | }
12 |
13 | fun BaseFragment.showToast(text: String?) {
14 | this.activity?.let {
15 | Toast.makeText(it, text, Toast.LENGTH_SHORT).show()
16 | }
17 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/LiveDataExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/RequestExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import com.google.gson.Gson
4 | import me.ibrahimsn.core.domain.model.param.Param
5 | import me.ibrahimsn.core.domain.model.request.Request
6 |
7 | fun Request?.getHeaderParams(): List? {
8 | this?.headerParams?.let {
9 | return Gson().fromJson(it, Array::class.java)?.toList()
10 | }
11 |
12 | return null
13 | }
14 |
15 | fun Request?.getBodyParams(): List? {
16 | this?.bodyParams?.let {
17 | return Gson().fromJson(it, Array::class.java)?.toList()
18 | }
19 |
20 | return null
21 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/StringExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import okhttp3.Request
4 |
5 | fun String?.isValidUri(): Boolean {
6 | if (this.isNullOrEmpty()) return false
7 | return try {
8 | Request.Builder().url(this)
9 | true
10 | } catch (e: Exception) {
11 | false
12 | }
13 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/ViewExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import android.view.View
4 | import android.widget.CheckBox
5 | import android.widget.EditText
6 | import android.widget.TextView
7 |
8 | fun View?.show() {
9 | this?.visibility = View.VISIBLE
10 | }
11 |
12 | fun View?.dismiss() {
13 | this?.visibility = View.GONE
14 | }
15 |
16 | fun View?.showIf(condition: Boolean?) {
17 | this?.visibility = if (condition == true) View.VISIBLE else View.GONE
18 | }
19 |
20 | fun EditText?.setTextSilently(text: String?) {
21 | this?.tag = "#"
22 | this?.setText(text)
23 | this?.tag = null
24 | }
25 |
26 | fun CheckBox?.setCheckedSilently(isChecked: Boolean) {
27 | this?.tag = "#"
28 | this?.isChecked = isChecked
29 | this?.tag = null
30 | }
31 |
32 | fun TextView?.postText(text: String?) {
33 | this?.post {
34 | this.text = text
35 | }
36 | }
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/extension/WebsocketExt.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.extension
2 |
3 | import com.google.gson.Gson
4 | import me.ibrahimsn.core.domain.model.param.Param
5 | import me.ibrahimsn.core.domain.model.websocket.Websocket
6 |
7 | fun Websocket?.getHeaderParams(): List? {
8 | this?.headerParams?.let {
9 | return Gson().fromJson(it, Array::class.java)?.toList()
10 | }
11 |
12 | return null
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/livedata/SingleLiveEvent.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.livedata
2 |
3 | import androidx.annotation.MainThread
4 | import androidx.annotation.Nullable
5 | import androidx.lifecycle.LifecycleOwner
6 | import androidx.lifecycle.MutableLiveData
7 | import androidx.lifecycle.Observer
8 | import java.util.concurrent.atomic.AtomicBoolean
9 |
10 | class SingleLiveEvent: MutableLiveData() {
11 |
12 | private val pending = AtomicBoolean(false)
13 |
14 | @MainThread
15 | override fun observe(owner: LifecycleOwner, observer: Observer) {
16 | super.observe(owner, Observer { t ->
17 | if (pending.compareAndSet(true, false)) {
18 | observer.onChanged(t)
19 | }
20 | })
21 | }
22 |
23 | @MainThread
24 | override fun setValue(@Nullable t: T?) {
25 | pending.set(true)
26 | super.setValue(t)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/ui/param/ParamAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.ui.param
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.core.widget.addTextChangedListener
7 | import kotlinx.android.synthetic.main.row_param.view.*
8 | import me.ibrahimsn.core.R
9 | import me.ibrahimsn.core.domain.model.param.Param
10 | import me.ibrahimsn.core.presentation.base.BaseAdapter
11 | import me.ibrahimsn.core.presentation.base.BaseViewHolder
12 | import me.ibrahimsn.core.presentation.extension.setCheckedSilently
13 | import me.ibrahimsn.core.presentation.extension.setTextSilently
14 |
15 | class ParamAdapter(
16 | private val onParamsUpdatedListener: (List) -> Unit?
17 | ) : BaseAdapter() {
18 |
19 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ParamViewHolder {
20 | val view = LayoutInflater.from(parent.context).inflate(R.layout.row_param, parent, false)
21 | return ParamViewHolder(view)
22 | }
23 |
24 | fun addParam(param: Param) {
25 | items.add(param)
26 | notifyItemInserted(itemCount - 1)
27 | }
28 |
29 | fun setParams(params: List?) {
30 | params?.let {
31 | items.clear()
32 | items.addAll(params)
33 | notifyDataSetChanged()
34 | }
35 | }
36 |
37 | fun getParams(): List {
38 | return items
39 | }
40 |
41 | override fun areItemsTheSame(oldItem: Param, newItem: Param): Boolean {
42 | return oldItem.key == newItem.key
43 | }
44 |
45 | override fun areContentsTheSame(oldItem: Param, newItem: Param): Boolean {
46 | return oldItem.value == newItem.value
47 | }
48 |
49 | inner class ParamViewHolder(private val view: View) : BaseViewHolder(view) {
50 |
51 | override fun bind(item: Param?) {
52 | super.bind(item)
53 |
54 | item?.let {
55 | view.cbActive.setCheckedSilently(it.isActive)
56 | view.etKey.setTextSilently(it.key)
57 | view.etValue.setTextSilently(it.value)
58 | }
59 | }
60 |
61 | init {
62 | view.cbActive.setOnCheckedChangeListener { _, isChecked ->
63 | boundItem?.apply {
64 | if (view.cbActive.tag == null) {
65 | isActive = isChecked
66 | onParamsUpdatedListener.invoke(items)
67 | }
68 | }
69 | }
70 |
71 | // May cause memory leaks! Needs refactor
72 | view.etKey.addTextChangedListener {
73 | boundItem?.apply {
74 | if (view.etKey.tag == null) {
75 | key = it.toString()
76 | onParamsUpdatedListener.invoke(items)
77 | }
78 | }
79 | }
80 |
81 | view.etValue.addTextChangedListener {
82 | boundItem?.apply {
83 | if (view.etValue.tag == null) {
84 | value = it.toString()
85 | onParamsUpdatedListener.invoke(items)
86 | }
87 | }
88 | }
89 |
90 | view.ibRemove.setOnClickListener {
91 | boundItem?.apply {
92 | val index = items.indexOf(this)
93 | items.removeAt(index)
94 | notifyItemRemoved(index)
95 | onParamsUpdatedListener(items)
96 | }
97 | }
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/view/progressButton/ProgressButton.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.view.progressButton
2 |
3 | import android.animation.ValueAnimator
4 | import android.content.Context
5 | import android.graphics.Canvas
6 | import android.graphics.Color
7 | import android.graphics.Paint
8 | import android.graphics.RectF
9 | import android.graphics.drawable.Drawable
10 | import android.util.AttributeSet
11 | import androidx.appcompat.widget.AppCompatImageButton
12 | import me.ibrahimsn.core.R
13 |
14 | class ProgressButton : AppCompatImageButton {
15 |
16 | private val loadingStrokeWidth = 5f
17 |
18 | private var icon: Drawable? = null
19 | private var reverseIcon: Drawable? = null
20 |
21 | private var loadingAngle = 0f
22 | private val loaderRect = RectF()
23 |
24 | private var _isReversed: Boolean = false
25 | private var _isProcessing: Boolean = false
26 |
27 | private val paintProgress = Paint().apply {
28 | isAntiAlias = true
29 | style = Paint.Style.STROKE
30 | color = Color.parseColor("#01D36D")
31 | strokeWidth = loadingStrokeWidth
32 | strokeCap = Paint.Cap.ROUND
33 | }
34 |
35 | override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
36 | super.onSizeChanged(w, h, oldw, oldh)
37 | loaderRect.set(
38 | loadingStrokeWidth,
39 | loadingStrokeWidth,
40 | width - loadingStrokeWidth,
41 | height - loadingStrokeWidth
42 | )
43 | }
44 |
45 | constructor(context: Context) : this(context, null)
46 | constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
47 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
48 | val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.ProgressButton, 0, 0)
49 | icon = typedArray.getDrawable(R.styleable.ProgressButton_icon)
50 | reverseIcon = typedArray.getDrawable(R.styleable.ProgressButton_reverseIcon)
51 | typedArray.recycle()
52 |
53 | setImageDrawable(icon)
54 | }
55 |
56 | var isReversed: Boolean get() = _isReversed
57 | set(value) {
58 | _isReversed = value
59 | setImageDrawable(
60 | if (value) reverseIcon else icon
61 | )
62 | }
63 |
64 | var isProgressing: Boolean get() = _isProcessing
65 | set(value) {
66 | _isProcessing = value
67 | isEnabled = !isProgressing
68 |
69 | if (isProgressing) {
70 | anim.start()
71 | } else {
72 | anim.end()
73 | }
74 | }
75 |
76 | private val anim = ValueAnimator.ofFloat(0f, 360f).apply {
77 | repeatMode = ValueAnimator.RESTART
78 | repeatCount = ValueAnimator.INFINITE
79 | duration = 500
80 |
81 | addUpdateListener {
82 | loadingAngle = it.animatedValue as Float
83 | invalidate()
84 | }
85 | }
86 |
87 | override fun onDraw(canvas: Canvas) {
88 | super.onDraw(canvas)
89 |
90 | if (isProgressing) {
91 | canvas.drawArc(loaderRect, loadingAngle, 35f, false, paintProgress)
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/view/tabView/TabItem.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.view.tabView
2 |
3 | import android.graphics.RectF
4 |
5 | data class TabItem(
6 | var title: String,
7 | var rect: RectF = RectF()
8 | )
9 |
--------------------------------------------------------------------------------
/core/src/main/java/me/ibrahimsn/core/presentation/view/tabView/TabParser.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core.presentation.view.tabView
2 |
3 | import android.content.Context
4 | import android.content.res.Resources
5 | import android.content.res.XmlResourceParser
6 | import androidx.annotation.XmlRes
7 |
8 | class TabParser(private val context: Context, @XmlRes res: Int) {
9 |
10 | private val parser: XmlResourceParser = context.resources.getXml(res)
11 |
12 | fun parse(): List {
13 | val items: MutableList = mutableListOf()
14 | var eventType: Int?
15 |
16 | do {
17 | eventType = parser.next()
18 | if (eventType == XmlResourceParser.START_TAG && parser.name == "item") {
19 | items.add(getTabConfig(parser))
20 | }
21 | } while (eventType != XmlResourceParser.END_DOCUMENT)
22 |
23 | return items
24 | }
25 |
26 | private fun getTabConfig(parser: XmlResourceParser): TabItem {
27 | val attributeCount = parser.attributeCount
28 | var itemText: String? = null
29 |
30 | for (index in 0 until attributeCount) {
31 | when (parser.getAttributeName(index)) {
32 | "title" -> {
33 | itemText = try {
34 | context.getString(parser.getAttributeResourceValue(index, 0))
35 | } catch (notFoundException: Resources.NotFoundException) {
36 | parser.getAttributeValue(index)
37 | }
38 | }
39 | }
40 | }
41 |
42 | return TabItem(itemText ?: "")
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_add_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_box.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method_delete.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method_get.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method_patch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method_post.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_method_put.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_param_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_response_status_fail.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_response_status_success.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_background_row.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
-
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_close_white_18dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_close_white_20dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_close_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_delete_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_expand_less_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_expand_more_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_keyboard_arrow_right_white_18dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_send_white_20dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable/ic_send_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/core/src/main/res/font/lato.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/core/src/main/res/font/lato_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/core/src/main/res/font/lato_bold.ttf
--------------------------------------------------------------------------------
/core/src/main/res/font/lato_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/core/src/main/res/font/lato_regular.ttf
--------------------------------------------------------------------------------
/core/src/main/res/layout/row_param.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
41 |
42 |
59 |
60 |
61 |
62 |
69 |
70 |
--------------------------------------------------------------------------------
/core/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/core/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #15171f
5 | #15171f
6 | #3eb63e
7 |
8 | #707593
9 |
10 | #3eb63e
11 | #f5a623
12 | #4a90e2
13 | #ed4b48
14 | #9C27B0
15 |
16 | #0D3EB63E
17 | #0DF5A623
18 | #0D4A90E2
19 | #0DED4B48
20 | #0C9C27B0
21 |
22 | #15171f
23 | #1c1e28
24 |
25 | #3eb63e
26 | #ed4b48
27 |
28 | #21212B
29 | #606060
30 |
31 | #ffffff
32 | #80ffffff
33 | #16ffffff
34 |
35 | #f3f3f3
36 | #acffffff
37 | #526d76
38 |
39 | #f51f1f29
40 |
41 |
--------------------------------------------------------------------------------
/core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Invalid parameters
4 | Empty Uri
5 | Empty request body
6 | Network error
7 | Invalid Uri
8 |
9 | Query Params
10 | Header Params
11 | Body Params
12 | Response
13 | Response
14 |
15 | Enter body data…
16 | Key
17 | Value
18 | https://api.server.com
19 | wss://socket.server.com
20 |
21 | Add
22 | New
23 | Clear
24 | Clear
25 | Send
26 |
27 | Delete
28 | Settings
29 |
30 | Requests
31 | Websockets
32 |
33 | WS
34 |
35 | GET
36 | POST
37 | PUT
38 | DEL
39 | PATCH
40 |
--------------------------------------------------------------------------------
/core/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 |
21 |
24 |
25 |
29 |
30 |
36 |
37 |
43 |
44 |
--------------------------------------------------------------------------------
/core/src/test/java/me/ibrahimsn/core/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.core
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feature/dashboard/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature/dashboard/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidLibrary
2 | apply from: "$rootDir/common.gradle"
3 |
4 | dependencies {
5 | implementation(project(Modules.core))
6 | implementation(project(Modules.navigation))
7 | }
8 |
--------------------------------------------------------------------------------
/feature/dashboard/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/feature/dashboard/consumer-rules.pro
--------------------------------------------------------------------------------
/feature/dashboard/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/feature/dashboard/src/androidTest/java/me/ibrahimsn/dashboard/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.dashboard.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/di/DashboardViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.di
2 |
3 | import me.ibrahimsn.core.domain.interactor.request.DeleteRequestsInteractor
4 | import me.ibrahimsn.core.domain.interactor.request.GetAllRequestsInteractor
5 | import me.ibrahimsn.core.domain.interactor.websocket.DeleteWebsocketsInteractor
6 | import me.ibrahimsn.core.domain.interactor.websocket.GetAllWebsocketsInteractor
7 | import me.ibrahimsn.dashboard.presentation.dashboard.DashboardViewModel
8 | import org.koin.androidx.viewmodel.dsl.viewModel
9 | import org.koin.core.qualifier.named
10 | import org.koin.dsl.module
11 |
12 | val dashboardViewModelModule = module {
13 |
14 | viewModel {
15 | DashboardViewModel(
16 | getAllRequestsInteractor = get(named(GetAllRequestsInteractor.NAME)),
17 | getAllWebsocketsInteractor = get(named(GetAllWebsocketsInteractor.NAME)),
18 | deleteRequestsInteractor = get(named(DeleteRequestsInteractor.NAME)),
19 | deleteWebsocketsInteractor = get(named(DeleteWebsocketsInteractor.NAME))
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/dashboard/DashboardViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.dashboard
2 |
3 | import androidx.lifecycle.viewModelScope
4 | import androidx.paging.LivePagedListBuilder
5 | import androidx.paging.PagedList
6 | import me.ibrahimsn.core.domain.interactor.Interactor
7 | import me.ibrahimsn.core.domain.interactor.request.DeleteRequestsInteractor
8 | import me.ibrahimsn.core.domain.interactor.websocket.DeleteWebsocketsInteractor
9 | import me.ibrahimsn.core.domain.model.request.Request
10 | import me.ibrahimsn.core.domain.model.websocket.Websocket
11 | import me.ibrahimsn.core.presentation.base.BaseViewModel
12 | import me.ibrahimsn.core.presentation.extension.io
13 |
14 | class DashboardViewModel(
15 | getAllRequestsInteractor: Interactor.PagingInteractor,
16 | getAllWebsocketsInteractor: Interactor.PagingInteractor,
17 | private val deleteRequestsInteractor: Interactor.RequestInteractor,
18 | private val deleteWebsocketsInteractor: Interactor.RequestInteractor
19 | ) : BaseViewModel() {
20 |
21 | private var _activeTab = 0
22 | var activeTab: Int get() = _activeTab
23 | set(value) { _activeTab = value }
24 |
25 | private val pagingConfig = PagedList.Config.Builder()
26 | .setEnablePlaceholders(false)
27 | .setPrefetchDistance(5)
28 | .setInitialLoadSizeHint(35)
29 | .setPageSize(25)
30 | .build()
31 |
32 | val pagedRequestLiveData = LivePagedListBuilder(
33 | getAllRequestsInteractor.invoke(),
34 | pagingConfig
35 | ).build()
36 |
37 | val pagedWebsocketLiveData = LivePagedListBuilder(
38 | getAllWebsocketsInteractor.invoke(),
39 | pagingConfig
40 | ).build()
41 |
42 | fun deleteRequests(requests: List?) {
43 | viewModelScope.io {
44 | deleteRequestsInteractor.invoke(
45 | DeleteRequestsInteractor.Params(requests)
46 | )
47 | }
48 | }
49 |
50 | fun deleteWebsockets(websockets: List?) {
51 | viewModelScope.io {
52 | deleteWebsocketsInteractor.invoke(
53 | DeleteWebsocketsInteractor.Params(websockets)
54 | )
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/dashboard/RequestsAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.dashboard
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.core.content.ContextCompat
7 | import androidx.recyclerview.widget.DiffUtil
8 | import kotlinx.android.synthetic.main.row_rest.view.*
9 | import me.ibrahimsn.core.domain.model.request.Request
10 | import me.ibrahimsn.core.presentation.base.BasePagedAdapter
11 | import me.ibrahimsn.core.presentation.base.BaseViewHolder
12 | import me.ibrahimsn.core.presentation.extension.toDateString
13 | import me.ibrahimsn.dashboard.R
14 |
15 | class RequestsAdapter(
16 | private val onRequestClickListener: (Request?, Int) -> Unit?,
17 | private val onRequestLongClickListener: (Request?, Int) -> Unit?,
18 | private val onClearSelectedItemsListener: () -> Unit?
19 | ) : BasePagedAdapter(DiffCallback) {
20 |
21 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RequestsViewHolder {
22 | val view = LayoutInflater.from(parent.context).inflate(R.layout.row_rest, parent, false)
23 | return RequestsViewHolder(view)
24 | }
25 |
26 | override fun getItemId(position: Int): Long {
27 | return getItem(position)?.id ?: 0
28 | }
29 |
30 | override fun onClearSelectedItems() {
31 | onClearSelectedItemsListener.invoke()
32 | }
33 |
34 | inner class RequestsViewHolder (private val view: View) : BaseViewHolder(view) {
35 |
36 | init {
37 | itemView.setOnClickListener {
38 | onRequestClickListener.invoke(boundItem, adapterPosition)
39 | }
40 |
41 | itemView.setOnLongClickListener {
42 | onRequestLongClickListener.invoke(boundItem, adapterPosition)
43 | true
44 | }
45 | }
46 |
47 | override fun bind(item: Request?) {
48 | super.bind(item)
49 |
50 | view.tvUri.text = boundItem?.uri
51 | view.tvTime.text = boundItem?.createdAt.toDateString()
52 | view.textViewMethod.text = boundItem?.method?.shortName
53 |
54 | boundItem?.method?.colorRes?.let {
55 | view.textViewMethod.setTextColor(
56 | ContextCompat.getColor(itemView.context, it)
57 | )
58 | }
59 |
60 | boundItem?.method?.backgroundRes?.let {
61 | view.textViewMethod.setBackgroundResource(it)
62 | }
63 |
64 | itemView.isSelected = isSelectedItem(adapterPosition)
65 | }
66 | }
67 |
68 | object DiffCallback : DiffUtil.ItemCallback() {
69 |
70 | override fun areItemsTheSame(oldItem: Request, newItem: Request): Boolean {
71 | return oldItem.id == newItem.id
72 | }
73 |
74 | override fun areContentsTheSame(oldItem: Request, newItem: Request): Boolean {
75 | return oldItem.uri == newItem.uri &&
76 | oldItem.method == newItem.method &&
77 | oldItem.headerParams == newItem.headerParams &&
78 | oldItem.bodyParams == newItem.bodyParams
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/dashboard/WebsocketsAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.dashboard
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.recyclerview.widget.DiffUtil
7 | import kotlinx.android.synthetic.main.row_ws.view.*
8 | import me.ibrahimsn.core.domain.model.websocket.Websocket
9 | import me.ibrahimsn.core.presentation.base.BasePagedAdapter
10 | import me.ibrahimsn.core.presentation.base.BaseViewHolder
11 | import me.ibrahimsn.core.presentation.extension.toDateString
12 | import me.ibrahimsn.dashboard.R
13 |
14 | class WebsocketsAdapter(
15 | private val onWebsocketClickListener: (Websocket?, Int) -> Unit?,
16 | private val onWebsocketLongClickListener: (Websocket?, Int) -> Unit?,
17 | private val onClearSelectedItemsListener: () -> Unit?
18 | ) : BasePagedAdapter(DiffCallback) {
19 |
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WebsocketsViewHolder {
21 | val view = LayoutInflater.from(parent.context).inflate(R.layout.row_ws, parent, false)
22 | return WebsocketsViewHolder(view)
23 | }
24 |
25 | override fun getItemId(position: Int): Long {
26 | return getItem(position)?.id ?: 0
27 | }
28 |
29 | override fun onClearSelectedItems() {
30 | onClearSelectedItemsListener.invoke()
31 | }
32 |
33 | inner class WebsocketsViewHolder (private val view: View) : BaseViewHolder(view) {
34 |
35 | init {
36 | itemView.setOnClickListener {
37 | onWebsocketClickListener.invoke(boundItem, adapterPosition)
38 | }
39 |
40 | itemView.setOnLongClickListener {
41 | onWebsocketLongClickListener.invoke(boundItem, adapterPosition)
42 | true
43 | }
44 | }
45 |
46 | override fun bind(item: Websocket?) {
47 | super.bind(item)
48 |
49 | view.tvUri.text = boundItem?.uri
50 | view.tvTime.text = boundItem?.createdAt.toDateString()
51 |
52 | itemView.isSelected = isSelectedItem(adapterPosition)
53 | }
54 | }
55 |
56 | object DiffCallback : DiffUtil.ItemCallback() {
57 |
58 | override fun areItemsTheSame(oldItem: Websocket, newItem: Websocket): Boolean {
59 | return oldItem.id == newItem.id
60 | }
61 |
62 | override fun areContentsTheSame(oldItem: Websocket, newItem: Websocket): Boolean {
63 | return oldItem == newItem
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/home/HomeActivity.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.home
2 |
3 | import android.content.Intent
4 | import android.util.DisplayMetrics
5 | import android.view.MenuItem
6 | import androidx.appcompat.widget.Toolbar
7 | import androidx.navigation.findNavController
8 | import androidx.navigation.ui.setupWithNavController
9 | import com.google.android.gms.ads.*
10 | import kotlinx.android.synthetic.main.activity_home.*
11 | import me.ibrahimsn.core.presentation.Constants
12 | import me.ibrahimsn.core.presentation.base.BaseActivity
13 | import me.ibrahimsn.core.presentation.extension.setNonPersonalized
14 | import me.ibrahimsn.core.presentation.model.ConsentManager
15 | import me.ibrahimsn.dashboard.R
16 | import me.ibrahimsn.dashboard.presentation.settings.SettingsActivity
17 |
18 | class HomeActivity : BaseActivity() {
19 |
20 | private lateinit var adView: AdView
21 |
22 | private val adSize: AdSize
23 | get() {
24 | val outMetrics = DisplayMetrics()
25 | windowManager.defaultDisplay.getMetrics(outMetrics)
26 |
27 | val density = outMetrics.density
28 |
29 | var adWidthPixels = adContainer.width.toFloat()
30 | if (adWidthPixels == 0f) {
31 | adWidthPixels = outMetrics.widthPixels.toFloat()
32 | }
33 |
34 | val adWidth = (adWidthPixels / density).toInt()
35 | return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
36 | }
37 |
38 | override fun layoutRes() = R.layout.activity_home
39 |
40 | override fun menuRes() = R.menu.menu_home
41 |
42 | override fun toolbar(): Toolbar? = toolbar
43 |
44 | override fun showBackButton(): Boolean = true
45 |
46 | override fun initView() {
47 | toolbar.setupWithNavController(findNavController(R.id.navHost))
48 |
49 | MobileAds.initialize(this)
50 | MobileAds.setRequestConfiguration(
51 | RequestConfiguration.Builder().setTestDeviceIds(listOf(Constants.ADMOB_TEST_DEVICE)).build()
52 | )
53 |
54 | adView = AdView(this)
55 | adView.adUnitId = Constants.BANNER_AD_UNIT_ID
56 | adView.adSize = adSize
57 | adContainer.addView(adView)
58 |
59 | val adRequest = AdRequest.Builder()
60 | ConsentManager.getConsentStatus(this, true) { isPersonalized ->
61 | if (!isPersonalized) adRequest.setNonPersonalized()
62 | adView.loadAd(adRequest.build())
63 | }
64 | }
65 |
66 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
67 | when (item.itemId) {
68 | R.id.settings -> {
69 | startActivity(Intent(this, SettingsActivity::class.java))
70 | }
71 | }
72 | return super.onOptionsItemSelected(item)
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/settings/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.settings
2 |
3 | import android.view.MenuItem
4 | import androidx.appcompat.widget.Toolbar
5 | import kotlinx.android.synthetic.main.activity_home.*
6 | import me.ibrahimsn.core.presentation.base.BaseActivity
7 | import me.ibrahimsn.dashboard.R
8 |
9 | class SettingsActivity : BaseActivity() {
10 |
11 | override fun layoutRes(): Int = R.layout.activity_settings
12 |
13 | override fun titleRes(): Int? = R.string.title_settings
14 |
15 | override fun toolbar(): Toolbar? = toolbar
16 |
17 | override fun showBackButton(): Boolean = true
18 |
19 | override fun initView() {
20 | supportFragmentManager.beginTransaction()
21 | .replace(R.id.frameLayout, SettingsFragment.newInstance())
22 | .commit()
23 | }
24 |
25 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
26 | when (item.itemId) {
27 | android.R.id.home -> {
28 | finish()
29 | }
30 | }
31 | return super.onOptionsItemSelected(item)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/java/me/ibrahimsn/dashboard/presentation/settings/SettingsFragment.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard.presentation.settings
2 |
3 | import android.content.Intent
4 | import android.net.Uri
5 | import android.os.Bundle
6 | import android.view.View
7 | import androidx.preference.Preference
8 | import androidx.preference.PreferenceFragmentCompat
9 | import androidx.preference.SwitchPreference
10 | import me.ibrahimsn.core.presentation.Constants
11 | import me.ibrahimsn.core.presentation.model.ConsentManager
12 | import me.ibrahimsn.dashboard.R
13 |
14 | class SettingsFragment : PreferenceFragmentCompat() {
15 |
16 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
17 | setPreferencesFromResource(R.xml.settings, rootKey)
18 | }
19 |
20 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
21 | super.onViewCreated(view, savedInstanceState)
22 | val consentPreference = findPreference("key_consent_status_value")
23 | val privacyPreference = findPreference("key_privacy_policy")
24 |
25 | ConsentManager.getConsentStatus(context!!, false) {
26 | consentPreference?.isChecked = it
27 | }
28 |
29 | consentPreference?.setOnPreferenceChangeListener { _, newValue ->
30 | ConsentManager.setConsentStatus(context!!, newValue as Boolean)
31 | true
32 | }
33 |
34 | privacyPreference?.setOnPreferenceClickListener {
35 | startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(Constants.PRIVACY_URL)))
36 | true
37 | }
38 | }
39 |
40 | companion object {
41 | fun newInstance() = SettingsFragment()
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/activity_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
23 |
24 |
29 |
30 |
31 |
32 |
42 |
43 |
48 |
49 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
23 |
24 |
29 |
30 |
31 |
32 |
38 |
39 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/fragment_dashboard.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
24 |
25 |
32 |
33 |
37 |
38 |
39 |
40 |
48 |
49 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/fragment_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/row_rest.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
25 |
26 |
31 |
32 |
39 |
40 |
46 |
47 |
48 |
49 |
53 |
54 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/layout/row_ws.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
25 |
26 |
31 |
32 |
39 |
40 |
46 |
47 |
48 |
49 |
53 |
54 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/menu/menu_action.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/menu/menu_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/menu/menu_tabs.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Settings
5 |
6 | Rest Client
7 | Legal
8 | About
9 |
10 | Follow Redirect
11 | Personalized Ads
12 | Privacy Policy
13 | About
14 |
15 | Automatically follow redirects
16 | Show personalized ads
17 | Usage terms, privacy policies
18 | Web Developer Tools 2020
19 |
20 |
--------------------------------------------------------------------------------
/feature/dashboard/src/main/res/xml/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
15 |
16 |
17 |
18 |
21 |
22 |
27 |
28 |
33 |
34 |
35 |
36 |
39 |
40 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/feature/dashboard/src/test/java/me/ibrahimsn/dashboard/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.dashboard
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feature/request/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature/request/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidLibrary
2 | apply from: "$rootDir/common.gradle"
3 |
4 | dependencies {
5 | implementation(project(Modules.core))
6 | implementation(project(Modules.navigation))
7 | }
8 |
--------------------------------------------------------------------------------
/feature/request/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/feature/request/consumer-rules.pro
--------------------------------------------------------------------------------
/feature/request/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/feature/request/src/androidTest/java/me/ibrahimsn/request/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.request
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.request.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/feature/request/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature/request/src/main/java/me/ibrahimsn/request/di/RequestViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.request.di
2 |
3 | import me.ibrahimsn.core.domain.interactor.request.MakeRequestInteractor
4 | import me.ibrahimsn.core.domain.interactor.request.SaveOrUpdateRequestInteractor
5 | import me.ibrahimsn.core.domain.interactor.uri.GenerateUriInteractor
6 | import me.ibrahimsn.core.domain.interactor.uri.ParseUriParamsInteractor
7 | import me.ibrahimsn.request.presentation.request.RequestViewModel
8 | import org.koin.androidx.viewmodel.dsl.viewModel
9 | import org.koin.core.qualifier.named
10 | import org.koin.dsl.module
11 |
12 | val requestViewModelModule = module {
13 |
14 | viewModel {
15 | RequestViewModel(
16 | makeRequestInteractor = get(named(MakeRequestInteractor.NAME)),
17 | saveOrUpdateRequestInteractor = get(named(SaveOrUpdateRequestInteractor.NAME)),
18 | generateUriInteractor = get(named(GenerateUriInteractor.NAME)),
19 | parseUriParamsInteractor = get(named(ParseUriParamsInteractor.NAME))
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/feature/request/src/main/res/menu/menu_request_method.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/feature/request/src/test/java/me/ibrahimsn/request/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.request
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feature/websocket/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature/websocket/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidLibrary
2 | apply from: "$rootDir/common.gradle"
3 |
4 | dependencies {
5 | implementation(project(Modules.core))
6 | implementation(project(Modules.navigation))
7 | }
8 |
--------------------------------------------------------------------------------
/feature/websocket/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/feature/websocket/consumer-rules.pro
--------------------------------------------------------------------------------
/feature/websocket/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/feature/websocket/src/androidTest/java/me/ibrahimsn/websocket/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.websocket
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.websocket.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/feature/websocket/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature/websocket/src/main/java/me/ibrahimsn/websocket/di/WebsocketViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.websocket.di
2 |
3 | import me.ibrahimsn.core.domain.interactor.websocket.ConnectWebsocketInteractor
4 | import me.ibrahimsn.core.domain.interactor.websocket.SaveOrUpdateWebsocketInteractor
5 | import me.ibrahimsn.websocket.presentation.websocket.WebsocketViewModel
6 | import org.koin.androidx.viewmodel.dsl.viewModel
7 | import org.koin.core.qualifier.named
8 | import org.koin.dsl.module
9 |
10 | val websocketViewModelModule = module {
11 |
12 | viewModel {
13 | WebsocketViewModel(
14 | connectWebsocketInteractor = get(named(ConnectWebsocketInteractor.NAME)),
15 | saveOrUpdateWebsocketInteractor = get(named(SaveOrUpdateWebsocketInteractor.NAME))
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/feature/websocket/src/test/java/me/ibrahimsn/websocket/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.websocket
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Mar 20 20:30:59 EET 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/navigation/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/navigation/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Plugins.androidLibrary
2 | apply from: "$rootDir/common.gradle"
3 |
4 | dependencies {
5 | api Libraries.navigation
6 | api Libraries.navigationUi
7 | }
8 |
--------------------------------------------------------------------------------
/navigation/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibrahimsn98/web-dev-tools-android/41074c267a41358af53801bd2979bba062fe8310/navigation/consumer-rules.pro
--------------------------------------------------------------------------------
/navigation/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/navigation/src/androidTest/java/me/ibrahimsn/navigation/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.navigation
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.ibrahimsn.navigation.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/navigation/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/navigation/src/main/res/navigation/nav_graph.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
13 |
16 |
17 |
18 |
21 |
24 |
25 |
26 |
27 |
31 |
32 |
36 |
37 |
--------------------------------------------------------------------------------
/navigation/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dashboard
4 | Request
5 | Websocket
6 |
--------------------------------------------------------------------------------
/navigation/src/test/java/me/ibrahimsn/navigation/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.ibrahimsn.navigation
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name='webdevtools'
2 | include Modules.app
3 | include Modules.core
4 | include Modules.dashboard
5 | include Modules.request
6 | include Modules.websocket
7 | include Modules.navigation
8 |
--------------------------------------------------------------------------------