├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── themes.xml │ │ │ ├── drawable │ │ │ │ ├── ic_anime.jpg │ │ │ │ ├── ic_arts.jpg │ │ │ │ ├── ic_cars.jpg │ │ │ │ ├── ic_city.jpg │ │ │ │ ├── ic_dark.jpg │ │ │ │ ├── ic_food.jpg │ │ │ │ ├── ic_love.jpg │ │ │ │ ├── ic_macro.jpg │ │ │ │ ├── ic_music.jpg │ │ │ │ ├── ic_space.jpg │ │ │ │ ├── ic_tech.jpg │ │ │ │ ├── ic_words.jpg │ │ │ │ ├── ic_animals.jpg │ │ │ │ ├── ic_flowers.jpg │ │ │ │ ├── ic_nature.jpg │ │ │ │ ├── ic_splash.jpg │ │ │ │ ├── ic_sports.jpg │ │ │ │ ├── ic_twitter.png │ │ │ │ ├── ic_vector.jpg │ │ │ │ ├── ic_abstract.jpg │ │ │ │ ├── ic_holidays.jpg │ │ │ │ ├── ic_instagram.png │ │ │ │ ├── ic_unsplash.png │ │ │ │ ├── ic_motorcycles.jpg │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── ic_launcher_foreground.xml │ │ │ │ └── ic_empty_bookmark.xml │ │ │ ├── font │ │ │ │ ├── robot_light.ttf │ │ │ │ ├── roboto_bold.ttf │ │ │ │ ├── roboto_thin.ttf │ │ │ │ ├── roboto_medium.ttf │ │ │ │ └── roboto_regular.ttf │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ └── values-night │ │ │ │ └── themes.xml │ │ ├── ic_background-playstore.png │ │ ├── ic_foreground-playstore.png │ │ ├── ic_launcher_background-playstore.png │ │ ├── java │ │ │ └── com │ │ │ │ └── eneskayiklik │ │ │ │ └── wallup │ │ │ │ ├── feature_detail │ │ │ │ ├── domain │ │ │ │ │ ├── model │ │ │ │ │ │ ├── DownloadType.kt │ │ │ │ │ │ ├── ScreenType.kt │ │ │ │ │ │ ├── DetailScreenNavArgs.kt │ │ │ │ │ │ ├── DetailState.kt │ │ │ │ │ │ └── DetailEvent.kt │ │ │ │ │ ├── repository │ │ │ │ │ │ └── DetailRepository.kt │ │ │ │ │ └── use_case │ │ │ │ │ │ └── DetailUseCase.kt │ │ │ │ ├── data │ │ │ │ │ └── repository │ │ │ │ │ │ └── DetailRepositoryImpl.kt │ │ │ │ └── presentation │ │ │ │ │ ├── component │ │ │ │ │ ├── DetailImageContent.kt │ │ │ │ │ ├── DetailImageItem.kt │ │ │ │ │ ├── DetailRelatedCollection.kt │ │ │ │ │ ├── LoadingAnim.kt │ │ │ │ │ ├── DetailButtonStack.kt │ │ │ │ │ └── DetailImageInfoItem.kt │ │ │ │ │ ├── DetailScreen.kt │ │ │ │ │ └── DetailViewModel.kt │ │ │ │ ├── WallUpApp.kt │ │ │ │ ├── feature_home │ │ │ │ ├── domain │ │ │ │ │ ├── model │ │ │ │ │ │ ├── ColorItem.kt │ │ │ │ │ │ ├── Category.kt │ │ │ │ │ │ ├── HomeState.kt │ │ │ │ │ │ ├── HomeEvent.kt │ │ │ │ │ │ └── UnsplashPhoto.kt │ │ │ │ │ ├── repository │ │ │ │ │ │ └── HomeRepository.kt │ │ │ │ │ └── use_case │ │ │ │ │ │ └── HomeUseCase.kt │ │ │ │ ├── presentation │ │ │ │ │ ├── component │ │ │ │ │ │ ├── SectionTitle.kt │ │ │ │ │ │ ├── WelcomeSection.kt │ │ │ │ │ │ ├── ColorSection.kt │ │ │ │ │ │ ├── CategoriesSection.kt │ │ │ │ │ │ └── SuggestedSection.kt │ │ │ │ │ ├── HomeViewModel.kt │ │ │ │ │ └── HomeScreen.kt │ │ │ │ └── data │ │ │ │ │ ├── dto │ │ │ │ │ └── UnsplashPhotoDto.kt │ │ │ │ │ └── repository │ │ │ │ │ └── HomeRepositoryImpl.kt │ │ │ │ ├── utils │ │ │ │ ├── const │ │ │ │ │ └── Constants.kt │ │ │ │ ├── model │ │ │ │ │ └── UiEvent.kt │ │ │ │ ├── network │ │ │ │ │ ├── Resource.kt │ │ │ │ │ └── HttpRoutes.kt │ │ │ │ ├── extensions │ │ │ │ │ ├── Context.kt │ │ │ │ │ ├── Int.kt │ │ │ │ │ └── LazyListScope.kt │ │ │ │ ├── broadcast_receiver │ │ │ │ │ ├── BroadcastReceiver.kt │ │ │ │ │ └── ShakeManager.kt │ │ │ │ ├── transfer_extensions │ │ │ │ │ └── UnsplashPhoto.kt │ │ │ │ └── blur_hash │ │ │ │ │ └── BlurHashDecoder.kt │ │ │ │ ├── feature_collection │ │ │ │ ├── domain │ │ │ │ │ ├── model │ │ │ │ │ │ ├── CollectionScreenNavArgs.kt │ │ │ │ │ │ └── CollectionState.kt │ │ │ │ │ ├── repository │ │ │ │ │ │ ├── SearchRepository.kt │ │ │ │ │ │ └── CollectionRepository.kt │ │ │ │ │ └── use_case │ │ │ │ │ │ ├── SearchUseCase.kt │ │ │ │ │ │ └── CollectionUseCase.kt │ │ │ │ ├── data │ │ │ │ │ ├── dto │ │ │ │ │ │ └── SearchResponseDto.kt │ │ │ │ │ └── repository │ │ │ │ │ │ ├── CollectionRepositoryImpl.kt │ │ │ │ │ │ └── SearchRepositoryImpl.kt │ │ │ │ └── presentation │ │ │ │ │ ├── component │ │ │ │ │ ├── TitleSection.kt │ │ │ │ │ └── ItemsSection.kt │ │ │ │ │ ├── CollectionScreen.kt │ │ │ │ │ └── CollectionViewModel.kt │ │ │ │ ├── feature_bookmark │ │ │ │ ├── domain │ │ │ │ │ ├── repository │ │ │ │ │ │ └── BookmarkRepository.kt │ │ │ │ │ ├── model │ │ │ │ │ │ └── BookmarkState.kt │ │ │ │ │ └── use_case │ │ │ │ │ │ └── BookmarkUseCase.kt │ │ │ │ ├── data │ │ │ │ │ ├── db │ │ │ │ │ │ ├── BookmarkDatabase.kt │ │ │ │ │ │ ├── entity │ │ │ │ │ │ │ └── BookmarkPhoto.kt │ │ │ │ │ │ └── dao │ │ │ │ │ │ │ └── BookmarkPhotoDao.kt │ │ │ │ │ └── repository │ │ │ │ │ │ └── BookmarkRepositoryImpl.kt │ │ │ │ └── presentation │ │ │ │ │ ├── BookmarkViewModel.kt │ │ │ │ │ ├── component │ │ │ │ │ ├── EmptyBookmarkSection.kt │ │ │ │ │ └── BookmarkSection.kt │ │ │ │ │ └── BookmarkScreen.kt │ │ │ │ ├── ui │ │ │ │ ├── theme │ │ │ │ │ ├── Shape.kt │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── Theme.kt │ │ │ │ │ └── Type.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── animation │ │ │ │ │ └── ScreensAnim.kt │ │ │ │ ├── di │ │ │ │ ├── DetailModule.kt │ │ │ │ └── HomeModule.kt │ │ │ │ └── feature_splash │ │ │ │ └── presentation │ │ │ │ └── SplashScreen.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── eneskayiklik │ │ │ └── wallup │ │ │ ├── ExampleUnitTest.kt │ │ │ └── utils │ │ │ └── extensions │ │ │ └── IntExtensionTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── eneskayiklik │ │ └── wallup │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── .idea ├── .gitignore ├── compiler.xml ├── vcs.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml └── misc.xml ├── screenshots ├── cover_photo.png ├── home_screen.jpg ├── detail_screen.jpg ├── bookmark_screen.jpg ├── collection_screen.jpg └── architecture_diagram.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── README.md ├── gradlew └── LICENSE /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | WallUp 3 | -------------------------------------------------------------------------------- /screenshots/cover_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/cover_photo.png -------------------------------------------------------------------------------- /screenshots/home_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/home_screen.jpg -------------------------------------------------------------------------------- /screenshots/detail_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/detail_screen.jpg -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /screenshots/bookmark_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/bookmark_screen.jpg -------------------------------------------------------------------------------- /screenshots/collection_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/collection_screen.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_anime.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_anime.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_arts.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_cars.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_city.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_city.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_dark.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_food.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_food.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_love.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_love.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_macro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_macro.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_music.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_music.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_space.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tech.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_tech.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_words.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_words.jpg -------------------------------------------------------------------------------- /app/src/main/res/font/robot_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/font/robot_light.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/roboto_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/font/roboto_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/roboto_thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/font/roboto_thin.ttf -------------------------------------------------------------------------------- /screenshots/architecture_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/screenshots/architecture_diagram.png -------------------------------------------------------------------------------- /app/src/main/ic_background-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/ic_background-playstore.png -------------------------------------------------------------------------------- /app/src/main/ic_foreground-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/ic_foreground-playstore.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_animals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_animals.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flowers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_flowers.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_nature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_nature.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_splash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_splash.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sports.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_sports.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_twitter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_vector.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_vector.jpg -------------------------------------------------------------------------------- /app/src/main/res/font/roboto_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/font/roboto_medium.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/roboto_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/font/roboto_regular.ttf -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_abstract.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_abstract.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_holidays.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_holidays.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_instagram.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_unsplash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_unsplash.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_motorcycles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/res/drawable/ic_motorcycles.jpg -------------------------------------------------------------------------------- /app/src/main/ic_launcher_background-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enes-Kayiklik/Wall-Up/HEAD/app/src/main/ic_launcher_background-playstore.png -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/model/DownloadType.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.model 2 | 3 | enum class DownloadType { 4 | SHARE, 5 | NONE 6 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/model/ScreenType.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.model 2 | 3 | enum class ScreenType { 4 | HOME, 5 | BOTH, 6 | LOCK 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/WallUpApp.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class WallUpApp: Application() -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_home/domain/model/ColorItem.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.domain.model 2 | 3 | data class ColorItem( 4 | val hexCode: String, 5 | val name: String = "", 6 | ) 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/model/DetailScreenNavArgs.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.model 2 | 3 | data class DetailScreenNavArgs( 4 | val id: String, 5 | val thumbnail: String? 6 | ) 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | rootProject.name = "WallUp" 9 | include ':app' 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/const/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.const 2 | 3 | const val UNSPLASH_URL = "https://unsplash.com/" 4 | 5 | const val TWITTER_LINK = "https://twitter.com/" 6 | const val INSTAGRAM_LINK = "https://www.instagram.com/" -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_home/domain/model/Category.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.domain.model 2 | 3 | import androidx.annotation.DrawableRes 4 | 5 | data class Category( 6 | val title: String = "", 7 | @DrawableRes val imageRes: Int = -1, 8 | ) 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/model/CollectionScreenNavArgs.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.model 2 | 3 | data class CollectionScreenNavArgs( 4 | val title: String?, 5 | val searchQuery: String?, 6 | val collectionId: String? 7 | ) 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_home/domain/model/HomeState.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.domain.model 2 | 3 | data class HomeState( 4 | val colorList: List = emptyList(), 5 | val categories: List = emptyList(), 6 | val randomPhotos: List? = null 7 | ) -------------------------------------------------------------------------------- /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/java/com/eneskayiklik/wallup/feature_home/domain/model/HomeEvent.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.domain.model 2 | 3 | import com.ramcosta.composedestinations.spec.Direction 4 | 5 | sealed class HomeEvent { 6 | data class Navigate(val route: Direction) : HomeEvent() 7 | object ScrollTop : HomeEvent() 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/domain/repository/BookmarkRepository.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.domain.repository 2 | 3 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 4 | 5 | interface BookmarkRepository { 6 | 7 | suspend fun getAllBookmarks(): List 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | .gradle 7 | /local.properties 8 | /.idea/caches 9 | /.idea/libraries 10 | /.idea/modules.xml 11 | /.idea/workspace.xml 12 | /.idea/navEditor.xml 13 | /.idea/assetWizardSettings.xml 14 | .DS_Store 15 | /build 16 | /captures 17 | .externalNativeBuild 18 | .cxx 19 | local.properties 20 | key_store 21 | *.keystore 22 | *.pepk 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/model/CollectionState.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.model 2 | 3 | import com.eneskayiklik.wallup.feature_home.domain.model.UnsplashPhoto 4 | 5 | data class CollectionState( 6 | val title: String = "", 7 | val count: Int = 0, 8 | val items: List = emptyList() 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/domain/model/BookmarkState.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.domain.model 2 | 3 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 4 | 5 | data class BookmarkState( 6 | val title: String = "Bookmarked Items", 7 | val count: Int = 0, 8 | val items: List = emptyList() 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/model/UiEvent.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.model 2 | 3 | import com.ramcosta.composedestinations.spec.Direction 4 | 5 | sealed class UiEvent { 6 | data class OnNavigate(val route: Direction) : UiEvent() 7 | object PopBack : UiEvent() 8 | object ScrollTop : UiEvent() 9 | data class ShowToast(val title: String) : UiEvent() 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.ui.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/repository/SearchRepository.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.repository 2 | 3 | import com.eneskayiklik.wallup.feature_home.data.dto.UnsplashPhotoDto 4 | import com.eneskayiklik.wallup.utils.network.Resource 5 | 6 | interface SearchRepository { 7 | 8 | suspend fun getSearchData(query: String): Resource> 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/data/dto/SearchResponseDto.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.data.dto 2 | 3 | import com.eneskayiklik.wallup.feature_home.data.dto.UnsplashPhotoDto 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class SearchResponseDto( 8 | val results: List, 9 | val total: Int, 10 | val total_pages: Int 11 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/repository/CollectionRepository.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.repository 2 | 3 | import com.eneskayiklik.wallup.feature_home.data.dto.UnsplashPhotoDto 4 | import com.eneskayiklik.wallup.utils.network.Resource 5 | 6 | interface CollectionRepository { 7 | 8 | suspend fun getCollectionData(collectionId: String): Resource> 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/network/Resource.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.network 2 | 3 | sealed class Resource( 4 | val response: T? = null, 5 | val errorMessage: String? = null 6 | ) { 7 | data class Success(val data: T) : Resource(data) 8 | data class Error(val message: String, val data: T? = null) : Resource(data, message) 9 | class Loading : Resource() 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/test/java/com/eneskayiklik/wallup/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup 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 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/model/DetailState.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.model 2 | 3 | import android.graphics.drawable.Drawable 4 | import com.eneskayiklik.wallup.feature_home.domain.model.UnsplashPhoto 5 | 6 | data class DetailState( 7 | val thumbnail: String? = null, 8 | val imageDrawable: Drawable? = null, 9 | val currentDownloadId: Long? = null, 10 | val imageDetail: UnsplashPhoto? = null 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val LightOnBackground = Color(0xFF1E3054) 6 | val LightBackground = Color(0xFFF4F7FD) 7 | val LightSurface = Color(0xFFFFFFFF) 8 | val DarkOnBackground = Color(0xFFF5CAC9) 9 | val DarkBackground = Color(0xFF0C1B3A) 10 | val DarkSurface = Color(0xFF162544) 11 | val LightPrimary = Color(0xFF1E3054) 12 | val DarkPrimary = Color(0xFFF5CAC9) 13 | val PrimaryVariant = Color(0xFF8A7D8F) -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/data/db/BookmarkDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.data.db 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 6 | import com.eneskayiklik.wallup.feature_bookmark.data.db.dao.BookmarkPhotoDao 7 | 8 | @Database(entities = [BookmarkPhoto::class], version = 1) 9 | abstract class BookmarkDatabase: RoomDatabase() { 10 | abstract fun bookmarkDao(): BookmarkPhotoDao 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/domain/use_case/BookmarkUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.domain.use_case 2 | 3 | import com.eneskayiklik.wallup.feature_bookmark.domain.repository.BookmarkRepository 4 | import com.eneskayiklik.wallup.utils.network.Resource 5 | import kotlinx.coroutines.flow.flow 6 | import javax.inject.Inject 7 | 8 | class BookmarkUseCase @Inject constructor( 9 | private val repository: BookmarkRepository 10 | ) { 11 | suspend fun getAllBookmarks() = repository.getAllBookmarks() 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/data/db/entity/BookmarkPhoto.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.data.db.entity 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "bookmark") 8 | data class BookmarkPhoto( 9 | @PrimaryKey(autoGenerate = true) val id: Int = 0, 10 | @ColumnInfo(name = "unsplash_id") val unsplashId: String, 11 | @ColumnInfo(name = "thumbnail") val thumbnail: String, 12 | @ColumnInfo(name = "hex_color") val color: String, 13 | ) 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/network/HttpRoutes.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.network 2 | 3 | object HttpRoutes { 4 | private const val BASE_URL = "https://api.unsplash.com" 5 | const val RANDOM_PHOTO = "$BASE_URL/photos/random" 6 | const val PHOTO = "$BASE_URL/photos" 7 | const val COLLECTION = "$BASE_URL/collections/{id}/photos" 8 | const val SEARCH = "$BASE_URL/search/photos" 9 | } 10 | 11 | object HttpParam { 12 | const val CLIENT_ID = "client_id" 13 | const val COUNT = "count" 14 | const val PER_PAGE = "per_page" 15 | const val QUERY = "query" 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/extensions/Context.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.extensions 2 | 3 | import android.content.Context 4 | import android.graphics.Bitmap 5 | import android.net.Uri 6 | import android.provider.MediaStore 7 | import java.io.ByteArrayOutputStream 8 | 9 | fun Context.getImageUri(bitmap: Bitmap?): Uri { 10 | val bytes = ByteArrayOutputStream() 11 | bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, bytes) 12 | val path = MediaStore.Images.Media.insertImage( 13 | contentResolver, bitmap, System.currentTimeMillis().toString(), null 14 | ) 15 | return Uri.parse(path) 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_home/domain/repository/HomeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.domain.repository 2 | 3 | import com.eneskayiklik.wallup.feature_home.data.dto.UnsplashPhotoDto 4 | import com.eneskayiklik.wallup.feature_home.domain.model.Category 5 | import com.eneskayiklik.wallup.feature_home.domain.model.ColorItem 6 | import com.eneskayiklik.wallup.utils.network.Resource 7 | 8 | interface HomeRepository { 9 | 10 | suspend fun getColorList(): List 11 | 12 | suspend fun getCategoryList(): List 13 | 14 | suspend fun getRandomPhotos(): Resource> 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/repository/DetailRepository.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.repository 2 | 3 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 4 | import com.eneskayiklik.wallup.feature_home.data.dto.UnsplashPhotoDto 5 | import com.eneskayiklik.wallup.utils.network.Resource 6 | 7 | interface DetailRepository { 8 | 9 | suspend fun getImageDetail(id: String): Resource 10 | 11 | suspend fun isBookmarked(id: String): Boolean 12 | 13 | suspend fun addBookmark(item: BookmarkPhoto) 14 | 15 | suspend fun removeBookmark(id: String) 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/data/repository/BookmarkRepositoryImpl.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.data.repository 2 | 3 | import com.eneskayiklik.wallup.feature_bookmark.domain.repository.BookmarkRepository 4 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 5 | import com.eneskayiklik.wallup.feature_bookmark.data.db.dao.BookmarkPhotoDao 6 | import javax.inject.Inject 7 | 8 | class BookmarkRepositoryImpl @Inject constructor( 9 | private val dao: BookmarkPhotoDao 10 | ): BookmarkRepository { 11 | 12 | override suspend fun getAllBookmarks(): List { 13 | return dao.getAllBookmarks() 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_home/presentation/component/SectionTitle.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_home.presentation.component 2 | 3 | import androidx.compose.material.MaterialTheme 4 | import androidx.compose.material.Text 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.ui.Modifier 7 | import androidx.compose.ui.graphics.Color 8 | import androidx.compose.ui.text.font.FontWeight 9 | import androidx.compose.ui.unit.sp 10 | 11 | @Composable 12 | fun SectionTitle( 13 | modifier: Modifier = Modifier, 14 | title: String 15 | ) { 16 | Text( 17 | text = title, 18 | style = MaterialTheme.typography.h6, 19 | modifier = modifier 20 | ) 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_bookmark/data/db/dao/BookmarkPhotoDao.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_bookmark.data.db.dao 2 | 3 | import androidx.room.* 4 | import com.eneskayiklik.wallup.feature_bookmark.data.db.entity.BookmarkPhoto 5 | 6 | @Dao 7 | interface BookmarkPhotoDao { 8 | 9 | @Query("SELECT * FROM bookmark WHERE unsplash_id = :id") 10 | fun getSingleBookmark(id: String): BookmarkPhoto? 11 | 12 | @Query("SELECT * FROM bookmark") 13 | fun getAllBookmarks(): List 14 | 15 | @Insert(onConflict = OnConflictStrategy.REPLACE) 16 | fun addBookmark(data: BookmarkPhoto) 17 | 18 | @Query("DELETE FROM bookmark WHERE unsplash_id = :id") 19 | fun removeBookmark(id: String) 20 | } -------------------------------------------------------------------------------- /app/src/test/java/com/eneskayiklik/wallup/utils/extensions/IntExtensionTest.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.extensions 2 | 3 | import com.google.common.truth.Truth.assertThat 4 | import org.junit.Test 5 | import org.junit.runner.RunWith 6 | import org.junit.runners.JUnit4 7 | 8 | @RunWith(JUnit4::class) 9 | class IntExtensionTest { 10 | 11 | @Test 12 | fun `validate parse count`() { 13 | val counts = listOf(100, 18_340, 372_992, 823_498_239, 9_384, 2_048) 14 | val results = listOf("100", "18.3K", "372.9K", "823.4M", "9.3K", "2K") 15 | val result = counts.map { it.parseCount() } 16 | result.forEachIndexed { index, s -> 17 | assertThat(s).isEqualTo(results[index]) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/eneskayiklik/wallup/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup 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("com.naber.wallup", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/di/DetailModule.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.di 2 | 3 | import android.app.DownloadManager 4 | import android.app.WallpaperManager 5 | import android.content.Context 6 | import dagger.Module 7 | import dagger.Provides 8 | import dagger.hilt.InstallIn 9 | import dagger.hilt.android.qualifiers.ApplicationContext 10 | import dagger.hilt.components.SingletonComponent 11 | import javax.inject.Singleton 12 | 13 | @Module 14 | @InstallIn(SingletonComponent::class) 15 | object DetailModule { 16 | 17 | @Singleton 18 | @Provides 19 | fun provideDownloadManager(@ApplicationContext context: Context): DownloadManager = 20 | context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager 21 | 22 | @Singleton 23 | @Provides 24 | fun provideWallpaperManager(@ApplicationContext context: Context): WallpaperManager = 25 | WallpaperManager.getInstance(context) 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/utils/extensions/Int.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.utils.extensions 2 | 3 | fun Int.parseCount(): String { 4 | return when (this) { 5 | in 1_000..999_999 -> { 6 | val result = StringBuilder("") 7 | val concat = this % 1000 8 | result.append("${this / 1_000}") 9 | if (concat >= 100) 10 | result.append(".${concat.toString().first()}") 11 | result.append("K") 12 | result.toString() 13 | } 14 | in 1_000_000..999_999_999 -> { 15 | val result = StringBuilder("") 16 | val concat = this % 1_000_000 17 | result.append("${this / 1_000_000}") 18 | if (concat >= 100) 19 | result.append(".${concat.toString().first()}") 20 | result.append("M") 21 | result.toString() 22 | } 23 | else -> "$this" 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_detail/domain/model/DetailEvent.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_detail.domain.model 2 | 3 | import android.content.Context 4 | import android.graphics.drawable.Drawable 5 | 6 | sealed class DetailEvent { 7 | data class OnBookmarkClick( 8 | val id: String, 9 | val thumbnail: String, 10 | val color: String, 11 | val addBookmark: Boolean 12 | ) : DetailEvent() 13 | 14 | data class OnDownloadClick(val url: String, val createdAt: String) : DetailEvent() 15 | data class OnWallpaper( 16 | val context: Context, 17 | val bitmap: Drawable? 18 | ) : DetailEvent() 19 | 20 | data class Navigate(val id: String?, val title: String? = null) : DetailEvent() 21 | data class UpdateDrawable(val drawable: Drawable?) : DetailEvent() 22 | data class Share(val drawable: Drawable?, val context: Context) : DetailEvent() 23 | data class ShareText(val data: String, val context: Context) : DetailEvent() 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/use_case/SearchUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.use_case 2 | 3 | import com.eneskayiklik.wallup.feature_collection.domain.repository.SearchRepository 4 | import com.eneskayiklik.wallup.utils.network.Resource 5 | import com.eneskayiklik.wallup.utils.transfer_extensions.toUIModel 6 | import kotlinx.coroutines.flow.flow 7 | import javax.inject.Inject 8 | 9 | class SearchUseCase @Inject constructor( 10 | private val repository: SearchRepository 11 | ) { 12 | suspend fun getSearchData(query: String) = flow { 13 | when (val data = repository.getSearchData(query)) { 14 | is Resource.Error -> emit(Resource.Error(data.message)) 15 | is Resource.Loading -> emit(Resource.Loading()) 16 | is Resource.Success -> { 17 | try { 18 | emit(Resource.Success(data.data.map { it.toUIModel() })) 19 | } catch (e: Exception) { 20 | emit(Resource.Error(e.message ?: "An unexpected error occurred")) 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/feature_collection/domain/use_case/CollectionUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.feature_collection.domain.use_case 2 | 3 | import com.eneskayiklik.wallup.feature_collection.domain.repository.CollectionRepository 4 | import com.eneskayiklik.wallup.utils.network.Resource 5 | import com.eneskayiklik.wallup.utils.transfer_extensions.toUIModel 6 | import kotlinx.coroutines.flow.flow 7 | import javax.inject.Inject 8 | 9 | class CollectionUseCase @Inject constructor( 10 | private val repository: CollectionRepository 11 | ) { 12 | suspend fun getCollectionData(collectionId: String) = flow { 13 | when (val data = repository.getCollectionData(collectionId)) { 14 | is Resource.Error -> emit(Resource.Error(data.message)) 15 | is Resource.Loading -> emit(Resource.Loading()) 16 | is Resource.Success -> { 17 | try { 18 | emit(Resource.Success(data.data.map { it.toUIModel() })) 19 | } catch (e: Exception) { 20 | emit(Resource.Error(e.message ?: "An unexpected error occurred")) 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /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=-Xmx2048m -Dfile.encoding=UTF-8 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 -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 14 | 19 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/eneskayiklik/wallup/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.eneskayiklik.wallup.ui.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = LightPrimary, 11 | primaryVariant = PrimaryVariant, 12 | background = DarkBackground, 13 | onBackground = DarkOnBackground, 14 | surface = DarkSurface, 15 | onSurface = DarkOnBackground 16 | ) 17 | 18 | private val LightColorPalette = lightColors( 19 | primary = DarkPrimary, 20 | primaryVariant = PrimaryVariant, 21 | background = LightBackground, 22 | onBackground = LightOnBackground, 23 | surface = LightSurface, 24 | onSurface = LightOnBackground 25 | ) 26 | 27 | @Composable 28 | fun WallUpTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { 29 | val colors = if (darkTheme) { 30 | DarkColorPalette 31 | } else { 32 | LightColorPalette 33 | } 34 | 35 | MaterialTheme( 36 | colors = colors, 37 | typography = Typography, 38 | shapes = Shapes, 39 | content = content 40 | ) 41 | } -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | 18 | 22 | 23 |