diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c0e251eff8..adf3dd63e8 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -2,6 +2,8 @@ plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("ru.practicum.android.diploma.plugins.developproperties")
+ id("com.google.devtools.ksp")
+ id("kotlin-parcelize")
}
android {
@@ -36,16 +38,30 @@ android {
buildFeatures {
buildConfig = true
+ viewBinding = true
}
}
dependencies {
implementation(libs.androidX.core)
implementation(libs.androidX.appCompat)
-
+ ksp(libs.room.compiler)
+ implementation(libs.room.runtime)
+ implementation(libs.room.ktx)
+ implementation(libs.kotlinx.coroutines.android)
+ implementation(libs.fragment.ktx)
// UI layer libraries
implementation(libs.ui.material)
implementation(libs.ui.constraintLayout)
+ implementation(libs.glide)
+ implementation(libs.retrofit.v290)
+ implementation(libs.converter.gson.v290)
+ implementation(libs.gson)
+ implementation(libs.koin.android)
+ implementation(libs.navigation.fragment.ktx)
+ implementation(libs.navigation.ui.ktx)
+ annotationProcessor(libs.compiler)
+ implementation(libs.byViewBinding)
// region Unit tests
testImplementation(libs.unitTests.junit)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 267e284599..18a9e33e89 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,7 +2,11 @@
+
+
+
+ android:screenOrientation="portrait"
+ android:exported="true"
+ tools:ignore="DiscouragedApi,LockedOrientationActivity">
@@ -22,5 +28,4 @@
-
-
\ No newline at end of file
+
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/db/AppDatabase.kt b/app/src/main/java/ru/practicum/android/diploma/data/db/AppDatabase.kt
new file mode 100644
index 0000000000..2e90c111b1
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/db/AppDatabase.kt
@@ -0,0 +1,11 @@
+package ru.practicum.android.diploma.data.db
+
+import androidx.room.Database
+import androidx.room.RoomDatabase
+
+@Database(
+ version = 1,
+ entities = [VacancyEntity::class]
+)
+abstract class AppDatabase : RoomDatabase()
+
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/db/VacancyEntity.kt b/app/src/main/java/ru/practicum/android/diploma/data/db/VacancyEntity.kt
new file mode 100644
index 0000000000..d5a1e03d7d
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/db/VacancyEntity.kt
@@ -0,0 +1,11 @@
+package ru.practicum.android.diploma.data.db
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "vacancy_table")
+data class VacancyEntity(
+ @PrimaryKey(autoGenerate = true)
+ val vacancyId: Int
+)
+
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/db/dao/VacancyDao.kt b/app/src/main/java/ru/practicum/android/diploma/data/db/dao/VacancyDao.kt
new file mode 100644
index 0000000000..4078d3a17f
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/db/dao/VacancyDao.kt
@@ -0,0 +1,7 @@
+package ru.practicum.android.diploma.data.db.dao
+
+import androidx.room.Dao
+
+@Dao
+interface VacancyDao
+
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/dto/Responce.kt b/app/src/main/java/ru/practicum/android/diploma/data/dto/Responce.kt
new file mode 100644
index 0000000000..d8013d9066
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/dto/Responce.kt
@@ -0,0 +1,10 @@
+package ru.practicum.android.diploma.data.dto
+
+const val RESULT_CODE_NO_INTERNET = -1
+const val RESULT_CODE_SUCCESS = 200
+const val RESULT_CODE_BAD_REQUEST = 400
+const val RESULT_CODE_SERVER_ERROR = 500
+
+class Responce {
+ var resultCode = 0
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/dto/SearchRequest.kt b/app/src/main/java/ru/practicum/android/diploma/data/dto/SearchRequest.kt
new file mode 100644
index 0000000000..2ae463e734
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/dto/SearchRequest.kt
@@ -0,0 +1,5 @@
+package ru.practicum.android.diploma.data.dto
+
+data class SearchRequest(
+ val options: Map
+)
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/dto/VacancyRequest.kt b/app/src/main/java/ru/practicum/android/diploma/data/dto/VacancyRequest.kt
new file mode 100644
index 0000000000..236acd0838
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/dto/VacancyRequest.kt
@@ -0,0 +1,5 @@
+package ru.practicum.android.diploma.data.dto
+
+data class VacancyRequest(
+ val id: Int
+)
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/network/HHApiService.kt b/app/src/main/java/ru/practicum/android/diploma/data/network/HHApiService.kt
new file mode 100644
index 0000000000..61c45fde27
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/network/HHApiService.kt
@@ -0,0 +1,21 @@
+package ru.practicum.android.diploma.data.network
+
+import retrofit2.http.GET
+import retrofit2.http.Headers
+import retrofit2.http.Path
+import retrofit2.http.QueryMap
+import ru.practicum.android.diploma.BuildConfig
+import ru.practicum.android.diploma.data.dto.Responce
+
+const val USER_AGENT_AUTHORIZATION = "Authorization: Bearer ${BuildConfig.HH_ACCESS_TOKEN}"
+const val USER_AGENT_APP_NAME = "HH-User-Agent: CareerHub (e.gasymov@hh.ru)"
+
+interface HHApiService {
+ @Headers(USER_AGENT_AUTHORIZATION, USER_AGENT_APP_NAME)
+ @GET("vacancies/{vacancy_id}")
+ suspend fun getVacancy(@Path("vacancy_id") id: Int): Responce
+
+ @Headers(USER_AGENT_AUTHORIZATION, USER_AGENT_APP_NAME)
+ @GET("vacancies")
+ suspend fun searchVacancies(@QueryMap options: Map): Responce
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/network/NetworkClient.kt b/app/src/main/java/ru/practicum/android/diploma/data/network/NetworkClient.kt
new file mode 100644
index 0000000000..0a3a0bd9b2
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/network/NetworkClient.kt
@@ -0,0 +1,7 @@
+package ru.practicum.android.diploma.data.network
+
+import ru.practicum.android.diploma.data.dto.Responce
+
+interface NetworkClient {
+ suspend fun doRequest(dto: Any): Responce
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/data/network/RetrofitNetworkClient.kt b/app/src/main/java/ru/practicum/android/diploma/data/network/RetrofitNetworkClient.kt
new file mode 100644
index 0000000000..a70fd915c9
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/data/network/RetrofitNetworkClient.kt
@@ -0,0 +1,54 @@
+package ru.practicum.android.diploma.data.network
+
+import android.content.Context
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import retrofit2.HttpException
+import ru.practicum.android.diploma.data.dto.RESULT_CODE_BAD_REQUEST
+import ru.practicum.android.diploma.data.dto.RESULT_CODE_NO_INTERNET
+import ru.practicum.android.diploma.data.dto.RESULT_CODE_SERVER_ERROR
+import ru.practicum.android.diploma.data.dto.RESULT_CODE_SUCCESS
+import ru.practicum.android.diploma.data.dto.Responce
+import ru.practicum.android.diploma.data.dto.SearchRequest
+import ru.practicum.android.diploma.data.dto.VacancyRequest
+import ru.practicum.android.diploma.util.isInternetAvailable
+
+class RetrofitNetworkClient(
+ private val hhApiService: HHApiService,
+ private val context: Context
+) : NetworkClient {
+
+ override suspend fun doRequest(dto: Any): Responce {
+ if (!isInternetAvailable(context)) {
+ return Responce().apply { resultCode = RESULT_CODE_NO_INTERNET }
+ }
+ return getResponce(dto = dto)
+ }
+
+ private suspend fun getResponce(dto: Any): Responce {
+ return withContext(Dispatchers.IO) {
+ try {
+ when (dto) {
+ is VacancyRequest -> {
+ val response = hhApiService.getVacancy(dto.id)
+ response.apply { resultCode = RESULT_CODE_SUCCESS }
+ }
+
+ is SearchRequest -> {
+ val response = hhApiService.searchVacancies(options = dto.options)
+ response.apply { resultCode = RESULT_CODE_SUCCESS }
+ }
+
+ else -> {
+ Responce().apply { resultCode = RESULT_CODE_BAD_REQUEST }
+ }
+ }
+
+ } catch (e: HttpException) {
+ println("RetrofitClient error code: ${e.code()} message: ${e.message}")
+ Responce().apply { resultCode = RESULT_CODE_SERVER_ERROR }
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/di/DataModule.kt b/app/src/main/java/ru/practicum/android/diploma/di/DataModule.kt
new file mode 100644
index 0000000000..eff76dc501
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/di/DataModule.kt
@@ -0,0 +1,35 @@
+package ru.practicum.android.diploma.di
+
+import androidx.room.Room
+import org.koin.android.ext.koin.androidContext
+import org.koin.dsl.module
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import ru.practicum.android.diploma.data.db.AppDatabase
+import ru.practicum.android.diploma.data.network.HHApiService
+import ru.practicum.android.diploma.data.network.NetworkClient
+import ru.practicum.android.diploma.data.network.RetrofitNetworkClient
+
+const val BASE_URL = "https://api.hh.ru/"
+val dataModule = module {
+ single {
+ RetrofitNetworkClient(
+ hhApiService = get(),
+ context = androidContext()
+ )
+ }
+
+ single {
+ Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+ .create(HHApiService::class.java)
+ }
+ single {
+ Room.databaseBuilder(androidContext(), AppDatabase::class.java, "database.db")
+ .fallbackToDestructiveMigration()
+ .build()
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/di/InteractorModule.kt b/app/src/main/java/ru/practicum/android/diploma/di/InteractorModule.kt
new file mode 100644
index 0000000000..364c0184dd
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/di/InteractorModule.kt
@@ -0,0 +1,7 @@
+package ru.practicum.android.diploma.di
+
+import org.koin.dsl.module
+
+val interactorModule = module {
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/di/RepositoryModule.kt b/app/src/main/java/ru/practicum/android/diploma/di/RepositoryModule.kt
new file mode 100644
index 0000000000..317f923070
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/di/RepositoryModule.kt
@@ -0,0 +1,7 @@
+package ru.practicum.android.diploma.di
+
+import org.koin.dsl.module
+
+val repositoryModule = module {
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/di/ViewModelModule.kt b/app/src/main/java/ru/practicum/android/diploma/di/ViewModelModule.kt
new file mode 100644
index 0000000000..c08d5fd3e9
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/di/ViewModelModule.kt
@@ -0,0 +1,7 @@
+package ru.practicum.android.diploma.di
+
+import org.koin.dsl.module
+
+val viewModelModule = module {
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FavouritesFragment.kt b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FavouritesFragment.kt
new file mode 100644
index 0000000000..449eb08409
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FavouritesFragment.kt
@@ -0,0 +1,24 @@
+package ru.practicum.android.diploma.ui.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
+import ru.practicum.android.diploma.databinding.FragmentFavouritesBinding
+
+class FavouritesFragment : Fragment() {
+
+ private val binding: FragmentFavouritesBinding by viewBinding(CreateMethod.INFLATE)
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return binding.root
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FilterFragment.kt b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FilterFragment.kt
new file mode 100644
index 0000000000..7432aff7ed
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/FilterFragment.kt
@@ -0,0 +1,34 @@
+package ru.practicum.android.diploma.ui.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
+import ru.practicum.android.diploma.R
+import ru.practicum.android.diploma.databinding.FragmentFilterBinding
+
+class FilterFragment : Fragment() {
+
+ private val binding: FragmentFilterBinding by viewBinding(CreateMethod.INFLATE)
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.buttonBackToSearchFromFilter.setOnClickListener {
+ findNavController().navigate(R.id.mainFragment)
+ }
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/fragments/SearchFragment.kt b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/SearchFragment.kt
new file mode 100644
index 0000000000..50bc2005f4
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/SearchFragment.kt
@@ -0,0 +1,38 @@
+package ru.practicum.android.diploma.ui.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
+import ru.practicum.android.diploma.R
+import ru.practicum.android.diploma.databinding.FragmentSearchBinding
+
+class SearchFragment : Fragment() {
+
+ private val binding: FragmentSearchBinding by viewBinding(CreateMethod.INFLATE)
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.buttonToFilter.setOnClickListener {
+ findNavController().navigate(R.id.action_searchFragment_to_filterFragment)
+ }
+
+ binding.buttonToVacancy.setOnClickListener {
+ findNavController().navigate(R.id.action_searchFragment_to_vacancyFragment)
+ }
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/fragments/TeamFragment.kt b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/TeamFragment.kt
new file mode 100644
index 0000000000..40ee0e2913
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/TeamFragment.kt
@@ -0,0 +1,24 @@
+package ru.practicum.android.diploma.ui.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
+import ru.practicum.android.diploma.databinding.FragmentTeamBinding
+
+class TeamFragment : Fragment() {
+
+ private val binding: FragmentTeamBinding by viewBinding(CreateMethod.INFLATE)
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return binding.root
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/fragments/VacancyFragment.kt b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/VacancyFragment.kt
new file mode 100644
index 0000000000..0328c61b23
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/fragments/VacancyFragment.kt
@@ -0,0 +1,34 @@
+package ru.practicum.android.diploma.ui.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
+import ru.practicum.android.diploma.R
+import ru.practicum.android.diploma.databinding.FragmentVacancyBinding
+
+class VacancyFragment : Fragment() {
+
+ private val binding: FragmentVacancyBinding by viewBinding(CreateMethod.INFLATE)
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.buttonBackToSearchFromVacancy.setOnClickListener {
+ findNavController().navigate(R.id.mainFragment)
+ }
+ }
+
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/ui/root/RootActivity.kt b/app/src/main/java/ru/practicum/android/diploma/ui/root/RootActivity.kt
index b02bd17d18..9509fcf6e6 100644
--- a/app/src/main/java/ru/practicum/android/diploma/ui/root/RootActivity.kt
+++ b/app/src/main/java/ru/practicum/android/diploma/ui/root/RootActivity.kt
@@ -2,13 +2,48 @@ package ru.practicum.android.diploma.ui.root
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.isVisible
+import androidx.navigation.fragment.NavHostFragment
+import androidx.navigation.ui.setupWithNavController
+import by.kirich1409.viewbindingdelegate.CreateMethod
+import by.kirich1409.viewbindingdelegate.viewBinding
import ru.practicum.android.diploma.BuildConfig
import ru.practicum.android.diploma.R
+import ru.practicum.android.diploma.databinding.ActivityRootBinding
class RootActivity : AppCompatActivity() {
+
+ private val binding: ActivityRootBinding by viewBinding(CreateMethod.INFLATE)
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_root)
+
+ setContentView(binding.root)
+
+ val navHostFragment = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment
+ val navController = navHostFragment.navController
+
+ binding.bottomNavigationView.setupWithNavController(navController)
+
+ navController.addOnDestinationChangedListener { _, destination, _ ->
+ when (destination.id) {
+ R.id.mainFragment -> {
+ binding.bottomNavigationView.isVisible = true
+ }
+
+ R.id.favoriteFragment -> {
+ binding.bottomNavigationView.isVisible = true
+ }
+
+ R.id.teamFragment -> {
+ binding.bottomNavigationView.isVisible = true
+ }
+
+ else -> {
+ binding.bottomNavigationView.isVisible = false
+ }
+ }
+ }
// Пример использования access token для HeadHunter API
networkRequestExample(accessToken = BuildConfig.HH_ACCESS_TOKEN)
diff --git a/app/src/main/java/ru/practicum/android/diploma/util/App.kt b/app/src/main/java/ru/practicum/android/diploma/util/App.kt
new file mode 100644
index 0000000000..04cb982990
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/util/App.kt
@@ -0,0 +1,24 @@
+package ru.practicum.android.diploma.util
+
+import android.app.Application
+import org.koin.android.ext.koin.androidContext
+import org.koin.core.context.startKoin
+import ru.practicum.android.diploma.di.dataModule
+import ru.practicum.android.diploma.di.interactorModule
+import ru.practicum.android.diploma.di.repositoryModule
+import ru.practicum.android.diploma.di.viewModelModule
+
+class App : Application() {
+ override fun onCreate() {
+ super.onCreate()
+ startKoin {
+ androidContext(this@App)
+ modules(
+ viewModelModule,
+ interactorModule,
+ repositoryModule,
+ dataModule
+ )
+ }
+ }
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/util/DebounceExtension.kt b/app/src/main/java/ru/practicum/android/diploma/util/DebounceExtension.kt
new file mode 100644
index 0000000000..d0e2479f70
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/util/DebounceExtension.kt
@@ -0,0 +1,40 @@
+package ru.practicum.android.diploma.util
+
+import android.view.View
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import ru.practicum.android.diploma.util.DebounceExtension.Companion.HALF_SECOND
+
+class DebounceExtension(
+ private val delayMillis: Long,
+ private val action: () -> Unit
+) {
+ companion object {
+ const val HALF_SECOND = 500L
+ }
+ private var debounceJob: Job? = null
+ fun debounce() {
+ debounceJob?.cancel()
+ debounceJob = CoroutineScope(Dispatchers.Main).launch {
+ delay(delayMillis)
+ action.invoke()
+ }
+ }
+}
+
+fun View.setDebouncedClickListener(
+ delayMillis: Long = HALF_SECOND,
+ onClick: () -> Unit
+) {
+ var debounceJob: Job? = null
+ setOnClickListener {
+ debounceJob?.cancel()
+ debounceJob = CoroutineScope(Dispatchers.Main).launch {
+ delay(delayMillis)
+ onClick()
+ }
+ }
+}
diff --git a/app/src/main/java/ru/practicum/android/diploma/util/NetworkUtils.kt b/app/src/main/java/ru/practicum/android/diploma/util/NetworkUtils.kt
new file mode 100644
index 0000000000..15c3e5e800
--- /dev/null
+++ b/app/src/main/java/ru/practicum/android/diploma/util/NetworkUtils.kt
@@ -0,0 +1,21 @@
+
+package ru.practicum.android.diploma.util
+
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+
+fun isInternetAvailable(context: Context): Boolean {
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
+ var result = false
+ if (capabilities != null) {
+ result = when {
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
+ else -> false
+ }
+ }
+ return result
+}
diff --git a/app/src/main/res/drawable/favorite_list_empty.webp b/app/src/main/res/drawable/favorite_list_empty.webp
new file mode 100644
index 0000000000..579a6b17e8
Binary files /dev/null and b/app/src/main/res/drawable/favorite_list_empty.webp differ
diff --git a/app/src/main/res/drawable/ic_arrow_back_16px.xml b/app/src/main/res/drawable/ic_arrow_back_16px.xml
new file mode 100644
index 0000000000..687feddaa0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow_back_16px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_arrow_forward_14px.xml b/app/src/main/res/drawable/ic_arrow_forward_14px.xml
new file mode 100644
index 0000000000..1c67cfceec
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow_forward_14px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_bottom_navigation_favorites_20px.xml b/app/src/main/res/drawable/ic_bottom_navigation_favorites_20px.xml
new file mode 100644
index 0000000000..6f3f74b05f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bottom_navigation_favorites_20px.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_bottom_navigation_main_20px.xml b/app/src/main/res/drawable/ic_bottom_navigation_main_20px.xml
new file mode 100644
index 0000000000..2fc4b7f5a5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bottom_navigation_main_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_bottom_navigation_team_20px.xml b/app/src/main/res/drawable/ic_bottom_navigation_team_20px.xml
new file mode 100644
index 0000000000..62bdf9f3ca
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bottom_navigation_team_20px.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_check_box_off_18px.xml b/app/src/main/res/drawable/ic_check_box_off_18px.xml
new file mode 100644
index 0000000000..4e79128d2e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check_box_off_18px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_check_box_on_18px.xml b/app/src/main/res/drawable/ic_check_box_on_18px.xml
new file mode 100644
index 0000000000..f0660527da
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check_box_on_18px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_circle_button_off_20px.xml b/app/src/main/res/drawable/ic_circle_button_off_20px.xml
new file mode 100644
index 0000000000..7c38e15687
--- /dev/null
+++ b/app/src/main/res/drawable/ic_circle_button_off_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_circle_button_on_20px.xml b/app/src/main/res/drawable/ic_circle_button_on_20px.xml
new file mode 100644
index 0000000000..845d1dc586
--- /dev/null
+++ b/app/src/main/res/drawable/ic_circle_button_on_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_close_cross_14px.xml b/app/src/main/res/drawable/ic_close_cross_14px.xml
new file mode 100644
index 0000000000..fa811ebf41
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close_cross_14px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_edit_text_cursor.xml b/app/src/main/res/drawable/ic_edit_text_cursor.xml
new file mode 100644
index 0000000000..198879ccc7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit_text_cursor.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_favorites_off_23px.xml b/app/src/main/res/drawable/ic_favorites_off_23px.xml
new file mode 100644
index 0000000000..3e70aeaa56
--- /dev/null
+++ b/app/src/main/res/drawable/ic_favorites_off_23px.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_favorites_on_20px.xml b/app/src/main/res/drawable/ic_favorites_on_20px.xml
new file mode 100644
index 0000000000..9704bb012d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_favorites_on_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_filter_off_12px.xml b/app/src/main/res/drawable/ic_filter_off_12px.xml
new file mode 100644
index 0000000000..3d49a8c915
--- /dev/null
+++ b/app/src/main/res/drawable/ic_filter_off_12px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_filter_on_24px.xml b/app/src/main/res/drawable/ic_filter_on_24px.xml
new file mode 100644
index 0000000000..895eec1309
--- /dev/null
+++ b/app/src/main/res/drawable/ic_filter_on_24px.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_loader_36px.xml b/app/src/main/res/drawable/ic_loader_36px.xml
new file mode 100644
index 0000000000..353f4ed834
--- /dev/null
+++ b/app/src/main/res/drawable/ic_loader_36px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_placeholder_30px.xml b/app/src/main/res/drawable/ic_placeholder_30px.xml
new file mode 100644
index 0000000000..0a01279897
--- /dev/null
+++ b/app/src/main/res/drawable/ic_placeholder_30px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_search_18px.xml b/app/src/main/res/drawable/ic_search_18px.xml
new file mode 100644
index 0000000000..47af517479
--- /dev/null
+++ b/app/src/main/res/drawable/ic_search_18px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_share_20px.xml b/app/src/main/res/drawable/ic_share_20px.xml
new file mode 100644
index 0000000000..660fff81fa
--- /dev/null
+++ b/app/src/main/res/drawable/ic_share_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/nav_color.xml b/app/src/main/res/drawable/nav_color.xml
new file mode 100644
index 0000000000..51351ef4ca
--- /dev/null
+++ b/app/src/main/res/drawable/nav_color.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/no_connection_sceleton_head.webp b/app/src/main/res/drawable/no_connection_sceleton_head.webp
new file mode 100644
index 0000000000..8a99bbf723
Binary files /dev/null and b/app/src/main/res/drawable/no_connection_sceleton_head.webp differ
diff --git a/app/src/main/res/drawable/no_such_list_found.webp b/app/src/main/res/drawable/no_such_list_found.webp
new file mode 100644
index 0000000000..7aadb909e8
Binary files /dev/null and b/app/src/main/res/drawable/no_such_list_found.webp differ
diff --git a/app/src/main/res/drawable/no_vacancy_list.webp b/app/src/main/res/drawable/no_vacancy_list.webp
new file mode 100644
index 0000000000..2cb57da1fe
Binary files /dev/null and b/app/src/main/res/drawable/no_vacancy_list.webp differ
diff --git a/app/src/main/res/drawable/search_image_default.webp b/app/src/main/res/drawable/search_image_default.webp
new file mode 100644
index 0000000000..f69ccca69f
Binary files /dev/null and b/app/src/main/res/drawable/search_image_default.webp differ
diff --git a/app/src/main/res/drawable/server_error_placeholder_search.webp b/app/src/main/res/drawable/server_error_placeholder_search.webp
new file mode 100644
index 0000000000..fb1e5cf2f2
Binary files /dev/null and b/app/src/main/res/drawable/server_error_placeholder_search.webp differ
diff --git a/app/src/main/res/drawable/server_error_placeholder_vacancy.webp b/app/src/main/res/drawable/server_error_placeholder_vacancy.webp
new file mode 100644
index 0000000000..65f8978e67
Binary files /dev/null and b/app/src/main/res/drawable/server_error_placeholder_vacancy.webp differ
diff --git a/app/src/main/res/font/ys_display_bold.ttf b/app/src/main/res/font/ys_display_bold.ttf
new file mode 100644
index 0000000000..f9b3f03cce
Binary files /dev/null and b/app/src/main/res/font/ys_display_bold.ttf differ
diff --git a/app/src/main/res/font/ys_display_medium.ttf b/app/src/main/res/font/ys_display_medium.ttf
new file mode 100644
index 0000000000..cc63032e21
Binary files /dev/null and b/app/src/main/res/font/ys_display_medium.ttf differ
diff --git a/app/src/main/res/font/ys_display_regular.ttf b/app/src/main/res/font/ys_display_regular.ttf
new file mode 100644
index 0000000000..02173eb829
Binary files /dev/null and b/app/src/main/res/font/ys_display_regular.ttf differ
diff --git a/app/src/main/res/layout/activity_root.xml b/app/src/main/res/layout/activity_root.xml
index ea46b92d7b..5d0d44e0b4 100644
--- a/app/src/main/res/layout/activity_root.xml
+++ b/app/src/main/res/layout/activity_root.xml
@@ -6,14 +6,40 @@
android:layout_height="match_parent"
tools:context=".ui.root.RootActivity">
-
+
+
+
+
+ app:menu="@menu/bottom_navigation_menu" />
+
+
+
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_favourites.xml b/app/src/main/res/layout/fragment_favourites.xml
new file mode 100644
index 0000000000..97b73e1ce0
--- /dev/null
+++ b/app/src/main/res/layout/fragment_favourites.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_filter.xml b/app/src/main/res/layout/fragment_filter.xml
new file mode 100644
index 0000000000..82b7e40871
--- /dev/null
+++ b/app/src/main/res/layout/fragment_filter.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
new file mode 100644
index 0000000000..d6dadaf2d1
--- /dev/null
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_team.xml b/app/src/main/res/layout/fragment_team.xml
new file mode 100644
index 0000000000..7f9d5e98dd
--- /dev/null
+++ b/app/src/main/res/layout/fragment_team.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_vacancy.xml b/app/src/main/res/layout/fragment_vacancy.xml
new file mode 100644
index 0000000000..4566d9fe60
--- /dev/null
+++ b/app/src/main/res/layout/fragment_vacancy.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/bottom_navigation_menu.xml b/app/src/main/res/menu/bottom_navigation_menu.xml
new file mode 100644
index 0000000000..84062a4856
--- /dev/null
+++ b/app/src/main/res/menu/bottom_navigation_menu.xml
@@ -0,0 +1,17 @@
+
+
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi/ic_launcher.xml
deleted file mode 100644
index 6f3b755bf5..0000000000
--- a/app/src/main/res/mipmap-anydpi/ic_launcher.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
deleted file mode 100644
index 6f3b755bf5..0000000000
--- a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..628f97bf34
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
deleted file mode 100644
index c209e78ecd..0000000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..e5dc3cbb3e
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
deleted file mode 100644
index b2dfe3d1ba..0000000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..ab42cf9937
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
deleted file mode 100644
index 4f0f1d64e5..0000000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..9fffe2849e
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
deleted file mode 100644
index 62b611da08..0000000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..5268499474
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
deleted file mode 100644
index 948a3070fe..0000000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..f854e7187d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
deleted file mode 100644
index 1b9a6956b3..0000000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..b10b468182
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
deleted file mode 100644
index 28d4b77f9f..0000000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..ed1c331f5f
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9287f50836..0000000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..2a9150a622
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
deleted file mode 100644
index aa7d6427e6..0000000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..97a5ad8f76
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9126ae37cb..0000000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/navigation/main_navigation_graph.xml b/app/src/main/res/navigation/main_navigation_graph.xml
new file mode 100644
index 0000000000..a3522ce92f
--- /dev/null
+++ b/app/src/main/res/navigation/main_navigation_graph.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index b5195a2f79..471d126a52 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,7 +1,28 @@
-
-
\ No newline at end of file
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index c8524cd961..33da3fe4b9 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,5 +1,11 @@
- #FF000000
- #FFFFFFFF
-
\ No newline at end of file
+ #1A1B22
+ #FDFDFD
+ #3772E7
+ #AEAFB4
+ #E6E8EB
+ #F56B6C
+
+ #1A1B2280
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..e37d8375aa
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,34 @@
+
+
+ 12sp
+ 16sp
+ 22sp
+ 32sp
+ 64dp
+ 48dp
+ 48dp
+ 0dp
+ 1dp
+ 3dp
+ 4dp
+ 6dp
+ 8dp
+ 11dp
+ 12dp
+ 16dp
+ 20dp
+ 32dp
+ 38dp
+ 42dp
+ 56dp
+ 60dp
+ 72dp
+ 160dp
+ 8dp
+ 16dp
+ 19dp
+ 24dp
+ 35dp
+
+ 1dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index db07d25c68..611d322928 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,59 @@
Practicum-Android-Diploma
-
\ No newline at end of file
+ Главная
+ Избранное
+ Команда
+ Поиск вакансий
+ Введите запрос
+ Нет интернета
+ Не удалось получить\n список вакансий
+ Настройки фильтрации
+ Место работы
+ Отрасль
+ Ожидаемая зарплата
+ Введите сумму
+ Не показывать без зарплаты
+ Выбор места работы
+ Страна
+ Регион
+ Выбор страны
+ Выбор региона
+ Введите регион
+ Такого региона нет
+ Не удалось получить список
+ Найдено %d вакансий
+ Выбрать
+ Применить
+ Сбросить
+ Выбор отрасли
+ Введите отрасль
+ Вакансия
+ Требуемый опыт
+ от
+ до
+ Зарплата не указана
+ Описание вакансии
+ Обязанности
+ Требования
+ Условия
+ Ключевые навыки
+ Контакты
+ Контактное лицо
+ E-mail
+ Телефон
+
+
+ Вакансия не найдена или удалена
+ Ошибка сервера
+ Список пуст
+ Таких вакансий нет
+
+ Над приложением работали
+ Гасымов Элчин Эмильевич
+ Королев Егор Алексеевич
+ Молоданов Виталий Олегович
+ Шокин Андрей Александрович
+ Рябицкий Андрей Игоревич
+
+
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 472697695a..8cdd5e1239 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,9 +1,30 @@
-
+
-
-
\ No newline at end of file
+
diff --git a/build-logic/checks/build.gradle.kts b/build-logic/checks/build.gradle.kts
index c8b1c9a17b..ef439d5288 100644
--- a/build-logic/checks/build.gradle.kts
+++ b/build-logic/checks/build.gradle.kts
@@ -10,4 +10,4 @@ dependencies {
implementation(libs.staticAnalysis.detektPlugin)
// workaround for https://github.com/gradle/gradle/issues/15383
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
-}
\ No newline at end of file
+}
diff --git a/build-logic/gradle-ext/build.gradle.kts b/build-logic/gradle-ext/build.gradle.kts
index 6092d7fdcf..eead1fc511 100644
--- a/build-logic/gradle-ext/build.gradle.kts
+++ b/build-logic/gradle-ext/build.gradle.kts
@@ -7,4 +7,4 @@ group = "ru.practicum.android.buildlogic"
dependencies {
// workaround for https://github.com/gradle/gradle/issues/15383
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
-}
\ No newline at end of file
+}
diff --git a/build.gradle.kts b/build.gradle.kts
index 541a66836c..b70254d398 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,6 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id("com.android.application") version "8.1.4" apply false
- id("org.jetbrains.kotlin.android") version "1.9.21" apply false
+ id("com.android.application") version "8.5.1" apply false
+ id("org.jetbrains.kotlin.android") version "2.0.0" apply false
id("convention.detekt")
+ id("com.google.devtools.ksp") version "2.0.0-1.0.21" apply false
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4518ee4f7a..36060caa43 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,10 +1,20 @@
[versions]
+converterGson = "2.9.0"
+fragmentKtx = "1.8.2"
+glide = "4.14.2"
+gson = "2.11.0"
java = "VERSION_1_8"
# Build constants
+koinAndroid = "3.5.6"
+kotlinxCoroutinesAndroid = "1.7.3"
minSdk = "26"
compileSdk = "34"
+navigationFragmentKtx = "2.7.7"
+retrofit = "2.11.0"
+retrofitVersion = "2.9.0"
+roomCompiler = "2.6.1"
targetSdk = "33"
# Detekt
@@ -14,6 +24,21 @@ detektTwitterComposeRules ="0.0.26"
[libraries]
# Detekt
+compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" }
+converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
+converter-gson-v290 = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
+fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" }
+glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
+gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
+koin-android = { module = "io.insert-koin:koin-android", version.ref = "koinAndroid" }
+kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutinesAndroid" }
+navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
+navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigationFragmentKtx" }
+retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
+retrofit-v290 = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofitVersion" }
+room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCompiler" }
+room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomCompiler" }
+room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomCompiler" }
staticAnalysis-detektPlugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
staticAnalysis-detektCli = { module = "io.gitlab.arturbosch.detekt:detekt-cli", version.ref = "detekt" }
staticAnalysis-detektApi = { module = "io.gitlab.arturbosch.detekt:detekt-api", version.ref = "detekt" }
@@ -21,20 +46,21 @@ staticAnalysis-detektTest = { module = "io.gitlab.arturbosch.detekt:detekt-test"
staticAnalysis-detektFormatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
staticAnalysis-detektLibraries = { module = "io.gitlab.arturbosch.detekt:detekt-rules-libraries", version.ref = "detekt" }
staticAnalysis-detektTwitterComposeRules = { module = "com.twitter.compose.rules:detekt", version.ref = "detektTwitterComposeRules" }
+byViewBinding = "com.github.kirich1409:viewbindingpropertydelegate-full:1.5.9"
# AndroidX
-androidX-core = "androidx.core:core-ktx:1.12.0"
-androidX-appCompat = "androidx.appcompat:appcompat:1.6.1"
+androidX-core = "androidx.core:core-ktx:1.13.1"
+androidX-appCompat = "androidx.appcompat:appcompat:1.7.0"
# UI layer libraries
-ui-material = "com.google.android.material:material:1.10.0"
+ui-material = "com.google.android.material:material:1.12.0"
ui-constraintLayout = "androidx.constraintlayout:constraintlayout:2.1.4"
# Unit tests
unitTests-junit = "junit:junit:4.13.2"
# UI tests
-uiTests-junitExt = "androidx.test.ext:junit:1.1.5"
-uiTests-espressoCore = "androidx.test.espresso:espresso-core:3.5.1"
+uiTests-junitExt = "androidx.test.ext:junit:1.2.1"
+uiTests-espressoCore = "androidx.test.espresso:espresso-core:3.6.1"
[bundles]
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4a2256c801..e44bf76891 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Sun Nov 12 02:07:38 ALMT 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists