Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
638254d
Add API access token to develop.properties
valtherys May 15, 2026
568381f
feat: добавила файлы Color, Theme, Type, Dimens, зависимости Compose …
valtherys May 15, 2026
568dc65
token added
h0mepvnk May 16, 2026
54de4c1
feat: debounce и проверка сети (closes #7)
denzelandrioki May 16, 2026
889a93f
review fixes
h0mepvnk May 16, 2026
b5ff5b6
review fixes
h0mepvnk May 16, 2026
0a407cb
review fixes
h0mepvnk May 16, 2026
dd2cc58
review fixes
h0mepvnk May 16, 2026
4c418df
chore: удалила файлы .idea из ПР
valtherys May 16, 2026
ac25591
chore: удалила файлы .idea из ПР
valtherys May 16, 2026
626c2ae
chore: удалила файлы .idea из ПР
valtherys May 16, 2026
97c0f8c
chore: удалила файлы .idea из ПР
valtherys May 16, 2026
e71aec6
review fixes
h0mepvnk May 17, 2026
009210f
review fixes
h0mepvnk May 17, 2026
15a59b7
review fixes
h0mepvnk May 17, 2026
721327f
detekt fixes
h0mepvnk May 17, 2026
96d72be
Merge pull request #13 from valtherys/feature/issue-7-helper-utils
valtherys May 18, 2026
6a9a871
Merge branch 'develop' into network-components
h0mepvnk May 18, 2026
3e862bd
all di files + reuse network connection checker
h0mepvnk May 18, 2026
31cb1e7
feat: иконка приложения из макета Icon store (closes #4)
denzelandrioki May 18, 2026
45ed82a
Merge pull request #2 from valtherys/feat_1
denzelandrioki May 18, 2026
fe475ec
feat: создала граф навигации, BottomNavView и фрагменты [задачи 9, 10]
valtherys May 18, 2026
23718f9
Merge remote-tracking branch 'origin/develop' into feat_9
valtherys May 18, 2026
3fccf0a
feat: создала Composable экранов [задачи 9, 10]
valtherys May 18, 2026
2799c9e
feat: refactor: удалила комментарии, исправила вызов функции в Choose…
valtherys May 18, 2026
412956b
style: стилизация в соответствии с предупреждениями линтеров [задачи …
valtherys May 18, 2026
a9704f7
style: стилизация в соответствии с предупреждениями линтеров [задачи …
valtherys May 18, 2026
35fe58e
review fixes
h0mepvnk May 18, 2026
d5dd95d
Merge branch 'develop' into network-components
h0mepvnk May 18, 2026
b206706
review fixes
h0mepvnk May 18, 2026
c654c1f
review fixes
h0mepvnk May 18, 2026
a3b607b
Merge pull request #12 from valtherys/network-components
denzelandrioki May 19, 2026
60ef93a
fix: detekt issues after merge PR #12
denzelandrioki May 19, 2026
287e50b
feat: добавлены базовые зависимости, подправлен code style
Deathriot May 19, 2026
ca0e453
refactor: привела к однообразию нейминг файлов [задачи 9, 10]
valtherys May 19, 2026
6fc7d4f
Merge branch develop into Feat_9
valtherys May 20, 2026
b9631ec
Merge pull request #21 from valtherys/feat_9
valtherys May 20, 2026
49e30a6
Merge branch 'develop' into feat_3
valtherys May 20, 2026
24bf161
Merge pull request #20 from valtherys/feature/issue-4-app-icon
valtherys May 20, 2026
5960ae9
Merge pull request #22 from valtherys/feat_3
valtherys May 20, 2026
1c3b228
feat: добавила элементы выдачи непустого воискового запроса [задача 16]
valtherys May 20, 2026
3900120
feat: добавила Box для наздачения BadgeItem z-индекса [задача 16]
valtherys May 21, 2026
4f960b1
feat_15: поиск вакансий — Data, Domain, ViewModel (#15)
denzelandrioki May 21, 2026
05090e1
feat: добавила пагинацию поиска, связала с viewModel [задача 18]
valtherys May 21, 2026
1e9848d
feat: добавила пагинацию поиска, связала с viewModel [задача 18]
valtherys May 21, 2026
0398a26
fix(feat_15): align ViewModel API with feat_16 and improve search layer
denzelandrioki May 21, 2026
1a04b8d
fix(feat_15): align Salary.kt with feat_16 to avoid merge conflict
denzelandrioki May 21, 2026
2507305
fix: remove invalid koin-androidx-viewmodel dependency for Koin 4
denzelandrioki May 21, 2026
5c79de7
refactor(feat_15): правки по ревью PR #25 — state и ViewModel
denzelandrioki May 21, 2026
816f380
feat: обновила JobSearchFragment.kt [задача 16]
valtherys May 21, 2026
3ec1795
fix: исправления по результатам ревью [16]
valtherys May 21, 2026
1cefd2e
fix(search): normalize query to lowercase in SearchInteractor
denzelandrioki May 22, 2026
d66b0fa
Merge pull request #25 from valtherys/feat_15
denzelandrioki May 22, 2026
fee0d90
chore: разрешение конфликтов в JobSearchViewModel [#16]
valtherys May 20, 2026
9faac5d
feat: добавила Box для наздачения BadgeItem z-индекса [задача 16]
valtherys May 21, 2026
97686c9
feat: обновила JobSearchFragment.kt [задача 16]
valtherys May 21, 2026
1edfaad
chore: разрешение конфликтов в JobSearchViewModel [#16]
valtherys May 21, 2026
d0bb901
chore: разрешение конфликтов в JobSearchState [#16]
valtherys May 21, 2026
d034903
Merge develop into feat_16 [16]
valtherys May 22, 2026
9873ecc
Merge remote-tracking branch 'origin/feat_16' into feat_16
valtherys May 22, 2026
53e6451
feat_14: recycler + preloader added
h0mepvnk May 21, 2026
5174b82
feat_14: review fixes
h0mepvnk May 22, 2026
112c840
feat_14: top bar fix
h0mepvnk May 22, 2026
064f2db
feat_14: detekt fix
h0mepvnk May 22, 2026
4402883
feat_14: dimen fix
h0mepvnk May 22, 2026
4a51763
Merge pull request #33 from valtherys/feat_14-search-screen
valtherys May 22, 2026
b5b4702
chore: разрешение конфликтов в JobSearch [#16]
valtherys May 20, 2026
7279f2f
chore: разрешение конфликтов в JobSearch [#16]
valtherys May 21, 2026
c97ff1e
chore: разрешение конфликтов в JobSearchState [#16]
valtherys May 21, 2026
800dafe
Merge develop into feat_16 [16]
valtherys May 22, 2026
9da93a7
Merge develop into feat_16 [задача 16]
valtherys May 20, 2026
b371aef
Merge develop into feat_16
valtherys May 21, 2026
b5d245d
Merge develop into feat_16
valtherys May 21, 2026
64cd544
Merge branch 'feat_16' into origin feat_16
valtherys May 22, 2026
d15ccdf
Merge branch develop into feat_16
valtherys May 22, 2026
24935da
Merge pull request #24 from valtherys/feat_16
valtherys May 22, 2026
c66a764
feat_18 добавила пагинацию вакансий. Поправила загрузку картинок в Va…
valtherys May 22, 2026
e17f48f
feat_17 : Добавлен начальный экран и обработка ошибок при поиске
Deathriot May 22, 2026
c6c4443
chore: исправления detect [#18]
valtherys May 22, 2026
43ad4eb
feat(team): экран «Команда» — UI по макету (#19)
denzelandrioki May 21, 2026
cd6d45b
fix(team): вынести hex-цвета в константы для detekt MagicNumber
denzelandrioki May 23, 2026
f8daad0
Merge pull request #34 from valtherys/feat_17
valtherys May 23, 2026
35031d0
Merge pull request #35 from valtherys/feat_18
valtherys May 23, 2026
1259411
Merge pull request #36 from valtherys/feat_19
valtherys May 23, 2026
8ba0318
fix: detekt warnings для CI iteration 1 review
denzelandrioki May 24, 2026
03a560d
feat_14: toast + top bar padding
h0mepvnk May 24, 2026
e1ecce7
feat_14: detekt
h0mepvnk May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# IntelliJ
*.iml
/.idea
/.idea/caches
/.idea/libraries
/.idea/modules.xml
Expand Down
54 changes: 52 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.ksp)

id("ru.practicum.android.diploma.plugins.developproperties")
}

Expand All @@ -11,6 +14,7 @@ android {
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {

applicationId = "ru.practicum.android.diploma"
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
Expand All @@ -34,6 +38,7 @@ android {
}
buildFeatures {
buildConfig = true
compose = true
}
}

Expand All @@ -44,14 +49,59 @@ kotlin {
}

dependencies {
// Core
implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.legacy.support.v4)
implementation(libs.lifecycle.livedata.ktx)
implementation(libs.lifecycle.viewmodel.ktx)

// UI layer libraries
implementation(libs.material)
implementation(libs.constraintlayout)
implementation(libs.firebase.crashlytics.buildtools)

implementation(libs.coroutines.core)
implementation(libs.coroutines.android)

implementation(platform(libs.compose.bom))
implementation(libs.compose.coil)
implementation("io.coil-kt.coil3:coil-network-okhttp:3.1.0")
implementation(libs.coil.svg)
implementation(libs.compose.ui)
implementation(libs.androidx.viewmodel)

testImplementation(libs.junit4)
testImplementation(libs.coroutines.test)
androidTestImplementation(libs.junit.ext)
androidTestImplementation(libs.espresso.core)
implementation(libs.navigation.fragment.ktx)
implementation(libs.navigation.ui.ktx)
implementation(libs.fragment.ktx)
implementation(libs.material.v180)

implementation(libs.material3)
implementation(libs.ui.tooling.preview)
debugImplementation(libs.ui.tooling)
implementation(libs.activity.compose)
implementation(libs.lifecycle.viewmodel.compose)

// Data layer
implementation(libs.retrofit)
implementation(libs.retrofit.converter)

ksp(libs.room.compiler)
implementation(libs.room.runtime)
implementation(libs.room.ktx)

// DI
implementation(libs.koin)

// Test
testImplementation(libs.junit4)
testImplementation(libs.coroutines.test)

androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.junit.ext)
androidTestImplementation(libs.espresso.core)
}
10 changes: 8 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".ui.root.App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -11,10 +15,12 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PracticumAndroidDiploma"
tools:ignore="LockedOrientationActivity"
tools:targetApi="31">
<activity
android:name=".ui.root.RootActivity"
android:exported="true">
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -23,4 +29,4 @@
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.practicum.android.diploma.data

import ru.practicum.android.diploma.data.dto.Response

interface NetworkClient {
suspend fun doRequest(dto: Any): Response<out Any>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.practicum.android.diploma.data

import ru.practicum.android.diploma.BuildConfig
import ru.practicum.android.diploma.domain.api.UserDataRepository

class UserDataRepositoryImpl : UserDataRepository {

override fun getAuthToken(): String = BuildConfig.API_ACCESS_TOKEN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ru.practicum.android.diploma.data

import ru.practicum.android.diploma.data.dto.VacanciesResponse
import ru.practicum.android.diploma.data.network.VacanciesRequest
import ru.practicum.android.diploma.domain.api.VacanciesRepository
import ru.practicum.android.diploma.domain.models.SearchVacanciesOutcome

class VacanciesRepositoryImpl(
private val networkClient: NetworkClient,
) : VacanciesRepository {

override suspend fun searchVacancies(searchText: String, page: Int): SearchVacanciesOutcome {
val response = networkClient.doRequest(
VacanciesRequest(searchText = searchText, page = page),
)
val data = response.data as? VacanciesResponse
return when {
response.resultCode != HTTP_OK || data == null -> SearchVacanciesOutcome.Error
else -> {
val domainResult = data.toDomain()
if (domainResult.vacancies.isEmpty()) {
SearchVacanciesOutcome.Empty
} else {
SearchVacanciesOutcome.Success(domainResult)
}
}
}
}

private companion object {
const val HTTP_OK = 200
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.practicum.android.diploma.data

import ru.practicum.android.diploma.data.dto.VacanciesResponse
import ru.practicum.android.diploma.data.dto.VacancyCardDto
import ru.practicum.android.diploma.data.dto.VacancyCardSalaryDto
import ru.practicum.android.diploma.domain.models.Salary
import ru.practicum.android.diploma.domain.models.VacanciesSearchResult
import ru.practicum.android.diploma.domain.models.Vacancy

internal fun VacanciesResponse.toDomain(): VacanciesSearchResult = VacanciesSearchResult(
found = found,
page = page,
pages = pages,
vacancies = items.map { it.toDomain() },
)

private fun VacancyCardDto.toDomain(): Vacancy = Vacancy(
id = id,
name = name,
company = company,
city = city,
salary = salary?.toDomain(),
logo = logo,
)

private fun VacancyCardSalaryDto.toDomain(): Salary = Salary(
from = from,
to = to,
currency = currency,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.practicum.android.diploma.data.dto

enum class Currency {
RUR,
RUB,
BYR,
USD,
EUR,
KZT,
UAH,
AZN,
UZS,
GEL,
KGT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.practicum.android.diploma.data.dto

data class FilterAreaDto(
val id: Int,
val name: String,
val parentId: Int?,
val areas: List<FilterAreaDto>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.practicum.android.diploma.data.dto

data class FilterIndustryDto(
val id: Int,
val name: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.practicum.android.diploma.data.dto

data class Response<T>(
val data: T?,
val resultCode: Int = 0,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.practicum.android.diploma.data.dto

data class VacanciesResponse(
val found: Int,
val pages: Int,
val page: Int,
val items: List<VacancyCardDto>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.practicum.android.diploma.data.dto

data class VacancyCardDto(
val id: String,
val name: String,
val company: String?,
val city: String?,
val salary: VacancyCardSalaryDto?,
val logo: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.practicum.android.diploma.data.dto

data class VacancyCardSalaryDto(
val from: Int?,
val to: Int?,
val currency: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ru.practicum.android.diploma.data.dto

data class VacancyDetailDto(
val id: String,
val name: String,
val description: String,
val salary: Salary?,
val address: Address?,
val experience: Experience?,
val schedule: Schedule?,
val employment: Employment?,
val contacts: Contacts?,
val employer: Employer,
val area: FilterAreaDto,
val skills: List<String>?,
val url: String,
val industry: FilterIndustryDto
)

data class Salary(
val from: Int?,
val to: Int?,
val currency: String?
)

data class Address(
val id: String,
val city: String,
val street: String,
val building: String,
val raw: String
)

data class Experience(
val id: String,
val name: String
)

data class Schedule(
val id: String,
val name: String
)

data class Employment(
val id: String,
val name: String
)

data class Contacts(
val id: String,
val name: String,
val email: String,
val phones: List<Phone>
)

data class Phone(
val comment: String?,
val formatted: String
)

data class Employer(
val id: String,
val name: String,
val logo: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.practicum.android.diploma.data.network

import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.QueryMap
import ru.practicum.android.diploma.data.dto.FilterAreaDto
import ru.practicum.android.diploma.data.dto.FilterIndustryDto
import ru.practicum.android.diploma.data.dto.VacanciesResponse
import ru.practicum.android.diploma.data.dto.VacancyDetailDto

interface ApiService {
@GET("/areas")
suspend fun getAreas(): List<FilterAreaDto>

@GET("/industries")
suspend fun getIndustries(): List<FilterIndustryDto>

@GET("/vacancies")
suspend fun getVacancies(
@QueryMap options: Map<String, String>
): VacanciesResponse

@GET("/vacancies/{id}")
suspend fun getVacancyDetails(
@Path("id") id: String
): VacancyDetailDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.practicum.android.diploma.data.network

object AreasRequest
Loading