├── .fleet
└── settings.json
├── .github
├── ci-gradle.properties
└── workflows
│ └── Check.yaml
├── .gitignore
├── LICENSE.txt
├── README.MD
├── assets
├── icon.png
├── screenshots
│ ├── android
│ │ ├── Screenshot_1.png
│ │ ├── Screenshot_2.png
│ │ ├── Screenshot_3.png
│ │ ├── Screenshot_4.png
│ │ ├── Screenshot_5.png
│ │ ├── Screenshot_6.png
│ │ ├── Screenshot_7.png
│ │ └── Screenshot_8.png
│ └── ios
│ │ ├── Screenshot_1.png
│ │ ├── Screenshot_2.png
│ │ ├── Screenshot_3.png
│ │ ├── Screenshot_4.png
│ │ ├── Screenshot_5.png
│ │ └── Screenshot_6.png
└── splashy_banner.png
├── build.gradle.kts
├── cleanup.sh
├── composeApp
├── build.gradle.kts
├── proguard-rules.pro
└── src
│ ├── androidDebug
│ └── res
│ │ └── values
│ │ └── strings.xml
│ ├── androidMain
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── kotlin
│ │ └── dev
│ │ │ └── ishubhamsingh
│ │ │ └── splashy
│ │ │ ├── App.android.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── SplashyApp.kt
│ │ │ └── core
│ │ │ ├── di
│ │ │ └── components
│ │ │ │ └── PlatformModule.kt
│ │ │ ├── presentation
│ │ │ └── SplashyTheme.kt
│ │ │ └── utils
│ │ │ ├── CommonUtils.kt
│ │ │ ├── DatabaseDriverFactory.kt
│ │ │ └── FileUtils.kt
│ └── res
│ │ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_monochrome.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_monochrome.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_monochrome.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_monochrome.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_monochrome.png
│ │ ├── values-v29
│ │ └── style.xml
│ │ └── values
│ │ ├── strings.xml
│ │ └── style.xml
│ ├── commonMain
│ ├── composeResources
│ │ ├── drawable
│ │ │ └── hat.png
│ │ ├── font
│ │ │ ├── lato_black.ttf
│ │ │ ├── lato_bold.ttf
│ │ │ ├── lato_light.ttf
│ │ │ ├── lato_regular.ttf
│ │ │ ├── lato_thin.ttf
│ │ │ └── lobster_regular.ttf
│ │ └── values
│ │ │ └── strings.xml
│ ├── kotlin
│ │ └── dev
│ │ │ └── ishubhamsingh
│ │ │ └── splashy
│ │ │ ├── App.kt
│ │ │ ├── core
│ │ │ ├── di
│ │ │ │ ├── ApplicationModule.kt
│ │ │ │ └── components
│ │ │ │ │ ├── CommonModule.kt
│ │ │ │ │ └── PlatformModule.kt
│ │ │ ├── domain
│ │ │ │ ├── NetworkResult.kt
│ │ │ │ ├── ScreenEvent.kt
│ │ │ │ └── UnsplashRepository.kt
│ │ │ ├── navigation
│ │ │ │ ├── SplashyAppState.kt
│ │ │ │ └── TopLevelScreen.kt
│ │ │ ├── network
│ │ │ │ ├── KtorLogger.kt
│ │ │ │ ├── UnsplashRepositoryImpl.kt
│ │ │ │ └── api
│ │ │ │ │ └── UnsplashApi.kt
│ │ │ ├── presentation
│ │ │ │ └── SplashyTheme.kt
│ │ │ └── utils
│ │ │ │ ├── CommonUtils.kt
│ │ │ │ ├── DIHelper.kt
│ │ │ │ ├── DatabaseDriverFactory.kt
│ │ │ │ ├── Extensions.kt
│ │ │ │ ├── FileUtils.kt
│ │ │ │ ├── Logging.kt
│ │ │ │ └── SettingsUtils.kt
│ │ │ ├── db
│ │ │ ├── Database.kt
│ │ │ ├── columnAdapters
│ │ │ │ ├── IntAdapter.kt
│ │ │ │ ├── LinksAdapter.kt
│ │ │ │ ├── TopicSubmissionsAdapter.kt
│ │ │ │ ├── UrlsAdapter.kt
│ │ │ │ └── UserAdapter.kt
│ │ │ └── mappers
│ │ │ │ ├── FavouriteMapper.kt
│ │ │ │ └── PhotoMapper.kt
│ │ │ ├── features
│ │ │ ├── about
│ │ │ │ └── ui
│ │ │ │ │ └── AboutComponent.kt
│ │ │ ├── categories
│ │ │ │ ├── CategoriesScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── CategoriesEvent.kt
│ │ │ │ │ ├── CategoriesState.kt
│ │ │ │ │ └── CategoriesTab.kt
│ │ │ ├── categoriesPhotos
│ │ │ │ ├── CategoriesPhotosScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── CategoriesPhotosEvent.kt
│ │ │ │ │ ├── CategoriesPhotosScreen.kt
│ │ │ │ │ └── CategoriesPhotosState.kt
│ │ │ ├── details
│ │ │ │ ├── DetailsScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── DetailsEvent.kt
│ │ │ │ │ ├── DetailsScreen.kt
│ │ │ │ │ └── DetailsState.kt
│ │ │ ├── favourites
│ │ │ │ ├── FavouritesScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── FavouritesEvent.kt
│ │ │ │ │ ├── FavouritesState.kt
│ │ │ │ │ └── FavouritesTab.kt
│ │ │ ├── home
│ │ │ │ ├── HomeScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ │ ├── HomeEvent.kt
│ │ │ │ │ ├── HomeState.kt
│ │ │ │ │ └── HomeTab.kt
│ │ │ └── settings
│ │ │ │ ├── SettingsScreenModel.kt
│ │ │ │ └── ui
│ │ │ │ ├── SettingsEvent.kt
│ │ │ │ ├── SettingsScreen.kt
│ │ │ │ └── SettingsState.kt
│ │ │ ├── models
│ │ │ ├── CollectionItem.kt
│ │ │ ├── DownloadUrl.kt
│ │ │ ├── Favourite.kt
│ │ │ ├── Links.kt
│ │ │ ├── LinksX.kt
│ │ │ ├── Photo.kt
│ │ │ ├── PhotoSearchCollection.kt
│ │ │ ├── ProfileImage.kt
│ │ │ ├── Social.kt
│ │ │ ├── Sponsor.kt
│ │ │ ├── Sponsorship.kt
│ │ │ ├── Topic.kt
│ │ │ ├── TopicFilter.kt
│ │ │ ├── TopicSubmissionStatus.kt
│ │ │ ├── TopicSubmissions.kt
│ │ │ ├── Urls.kt
│ │ │ └── User.kt
│ │ │ └── ui
│ │ │ ├── components
│ │ │ └── ComposeReusables.kt
│ │ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Typography.kt
│ └── sqldelight
│ │ └── dev
│ │ └── ishubhamsingh
│ │ └── splashy
│ │ └── db
│ │ ├── Favourite.sq
│ │ └── Photo.sq
│ └── iosMain
│ └── kotlin
│ └── dev
│ └── ishubhamsingh
│ └── splashy
│ ├── App.ios.kt
│ └── core
│ ├── di.components
│ └── PlatformModule.kt
│ ├── presentation
│ └── SplashyTheme.kt
│ └── utils
│ ├── CommonUtils.kt
│ ├── DatabaseDriverFactory.kt
│ └── FileUtils.kt
├── gradle.bat
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── iosApp
├── Configuration
│ └── Config.xcconfig
├── iosApp.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── iosApp.xcscheme
└── iosApp
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-20@2x.png
│ │ ├── AppIcon-20@2x~ipad.png
│ │ ├── AppIcon-20@3x.png
│ │ ├── AppIcon-20~ipad.png
│ │ ├── AppIcon-29.png
│ │ ├── AppIcon-29@2x.png
│ │ ├── AppIcon-29@2x~ipad.png
│ │ ├── AppIcon-29@3x.png
│ │ ├── AppIcon-29~ipad.png
│ │ ├── AppIcon-40@2x.png
│ │ ├── AppIcon-40@2x~ipad.png
│ │ ├── AppIcon-40@3x.png
│ │ ├── AppIcon-40~ipad.png
│ │ ├── AppIcon-60@2x~car.png
│ │ ├── AppIcon-60@3x~car.png
│ │ ├── AppIcon-83.5@2x~ipad.png
│ │ ├── AppIcon@2x.png
│ │ ├── AppIcon@2x~ipad.png
│ │ ├── AppIcon@3x.png
│ │ ├── AppIcon~ios-marketing.png
│ │ ├── AppIcon~ipad.png
│ │ └── Contents.json
│ └── Contents.json
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── info.plist
│ └── iosApp.swift
├── keystore
└── splashy.jks
├── renovate.json
├── settings.gradle.kts
└── spotless
└── copyright.txt
/.fleet/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true
3 | }
--------------------------------------------------------------------------------
/.github/ci-gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.daemon=false
2 | org.gradle.parallel=true
3 | org.gradle.jvmargs=-Xmx5120m
4 | org.gradle.workers.max=2
5 |
6 | kotlin.incremental=false
7 | kotlin.compiler.execution.strategy=in-process
--------------------------------------------------------------------------------
/.github/workflows/Check.yaml:
--------------------------------------------------------------------------------
1 | name: Check
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | concurrency:
12 | group: ci-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | build:
17 | runs-on: macos-latest
18 | timeout-minutes: 30
19 |
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v4
23 |
24 | - name: Copy CI gradle.properties
25 | run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
26 |
27 | - name: Retrieve the secret and decode it to a file
28 | env:
29 | SECRETS_BASE64: ${{ secrets.SECRETS_BASE64 }}
30 | run: |
31 | echo $SECRETS_BASE64 | base64 --decode > secrets.properties
32 |
33 | - name: Set up JDK 17
34 | uses: actions/setup-java@v4
35 | with:
36 | java-version: 17
37 | distribution: zulu
38 | cache: 'gradle'
39 |
40 | - name: Check formatting and build apk
41 | run: ./gradlew spotlessCheck lintRelease :composeApp:assembleRelease --stacktrace
42 |
43 | - name: Upload build outputs (APKs)
44 | uses: actions/upload-artifact@v4
45 | with:
46 | name: build-outputs
47 | path: composeApp/build/outputs/apk
48 |
49 | - name: Upload build reports
50 | if: always()
51 | uses: actions/upload-artifact@v4
52 | with:
53 | name: build-reports
54 | path: composeApp/build/reports
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.iml
3 | .gradle
4 | .idea
5 | .DS_Store
6 | build
7 | */build
8 | captures
9 | .externalNativeBuild
10 | .cxx
11 | .kotlin
12 | local.properties
13 | xcuserdata/
14 | *yarn.lock
15 | secrets.properties
16 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Splashy
11 |
12 |
13 | An Unsplash based wallpaper app built with Compose Multiplatform and KMP for Android and iOS.
14 |
15 | [](https://github.com/ishubhamsingh/Splashy/actions/workflows/Check.yaml)
16 |
17 |
18 | ## :hammer_and_wrench: Tech Stack
19 |
20 | - [Kotlin Mutliplatform](https://kotlinlang.org/lp/multiplatform/)
21 | - [Compose Multiplatform](https://www.jetbrains.com/lp/compose-multiplatform/)
22 | - [Ktor Client](https://ktor.io/)
23 | - [SQLDelight](https://cashapp.github.io/sqldelight/2.0.0/)
24 | - [Voyager](https://github.com/adrielcafe/voyager)
25 | - [Koin](https://insert-koin.io/)
26 | - [Kamel](https://github.com/Kamel-Media/Kamel)
27 | - [Napier](https://github.com/AAkira/Napier)
28 | - [Compose Icons](https://github.com/DevSrSouza/compose-icons)
29 | - [Moko Permissions](https://github.com/icerockdev/moko-permissions)
30 |
31 | ## :camera_flash: Screenshots
32 |
33 | ### Android
34 |
35 |
36 |
37 | ### iOS
38 |
39 |
40 |
41 | ## :gear: Build
42 |
43 | The app uses Unsplash API, hence you need to get your own API key from [here](https://unsplash.com/documentation).
44 | In order to sign your builds generate `splashy.jks` keystore and add keystore password, alias and store password in `secrets.properties`.
45 |
46 | secrets.properties would look like this:
47 | ```
48 | unsplash.access.key=#Add your unsplash key
49 | splashy.keystore.password=#Add your keystore password
50 | splashy.key.alias=#Add your key alias
51 | splashy.key.password=#Add your key password
52 | ```
53 |
54 | ## License
55 | ```
56 | Copyright Shubham Singh
57 |
58 | Licensed under the Apache License, Version 2.0 (the "License");
59 | you may not use this file except in compliance with the License.
60 | You may obtain a copy of the License at
61 |
62 | https://www.apache.org/licenses/LICENSE-2.0
63 |
64 | Unless required by applicable law or agreed to in writing, software
65 | distributed under the License is distributed on an "AS IS" BASIS,
66 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67 | See the License for the specific language governing permissions and
68 | limitations under the License.
69 | ```
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/icon.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_1.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_2.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_3.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_4.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_5.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_6.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_7.png
--------------------------------------------------------------------------------
/assets/screenshots/android/Screenshot_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/android/Screenshot_8.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_1.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_2.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_3.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_4.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_5.png
--------------------------------------------------------------------------------
/assets/screenshots/ios/Screenshot_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/screenshots/ios/Screenshot_6.png
--------------------------------------------------------------------------------
/assets/splashy_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/assets/splashy_banner.png
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import com.diffplug.gradle.spotless.SpotlessExtension
17 |
18 | plugins {
19 | alias(libs.plugins.multiplatform).apply(false)
20 | alias(libs.plugins.compose).apply(false)
21 | alias(libs.plugins.compose.compiler).apply(false)
22 | alias(libs.plugins.cocoapods).apply(false)
23 | alias(libs.plugins.android.application).apply(false)
24 | alias(libs.plugins.buildConfig).apply(false)
25 | alias(libs.plugins.kotlinx.serialization).apply(false)
26 | alias(libs.plugins.sqlDelight).apply(false)
27 | alias(libs.plugins.spotless).apply(false)
28 | }
29 |
30 | allprojects {
31 | apply(plugin = rootProject.libs.plugins.spotless.get().pluginId)
32 | configure {
33 | kotlin {
34 | ktfmt(libs.versions.ktfmt.get()).googleStyle()
35 | target("**/*.kt")
36 | targetExclude("$projectDir/build/**/*.kt")
37 | licenseHeaderFile(rootProject.file("spotless/copyright.txt"))
38 | }
39 | kotlinGradle {
40 | ktfmt(libs.versions.ktfmt.get()).googleStyle()
41 | target("**/*.kts")
42 | targetExclude("$projectDir/build/**/*.kts")
43 | licenseHeaderFile(rootProject.file("spotless/copyright.txt"), "(^(?![\\/ ]\\*).*$)")
44 | }
45 | format("xml") {
46 | target("**/*.xml")
47 | targetExclude("**/build/", ".idea/")
48 | trimTrailingWhitespace()
49 | endWithNewline()
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/cleanup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | rm -rf .idea
3 | ./gradlew clean
4 | rm -rf .gradle
5 | rm -rf build
6 | rm -rf */build
7 | rm -rf iosApp/iosApp.xcworkspace
8 | rm -rf iosApp/Pods
9 | rm -rf iosApp/iosApp.xcodeproj/project.xcworkspace
10 | rm -rf iosApp/iosApp.xcodeproj/xcuserdata
11 |
--------------------------------------------------------------------------------
/composeApp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -dontwarn org.slf4j.impl.StaticLoggerBinder
2 | -dontwarn kotlinx.serialization.KSerializer
3 | -dontwarn kotlinx.serialization.Serializable
4 | -keep class io.kamel.** { *; }
5 | -keep class dev.ishubhamsingh.splashy.models.** { *; }
--------------------------------------------------------------------------------
/composeApp/src/androidDebug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Splashy Debug
3 |
4 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/App.android.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import androidx.compose.runtime.Composable
20 |
21 | @Composable fun AppView() = App(darkTheme = isSystemInDarkTheme(), dynamicColor = true)
22 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy
17 |
18 | import android.os.Bundle
19 | import androidx.activity.compose.setContent
20 | import androidx.appcompat.app.AppCompatActivity
21 | import androidx.core.view.WindowCompat
22 |
23 | class MainActivity : AppCompatActivity() {
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 | WindowCompat.setDecorFitsSystemWindows(window, false)
27 | setContent { AppView() }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/SplashyApp.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy
17 |
18 | import android.app.Application
19 | import dev.ishubhamsingh.splashy.core.di.appModule
20 | import dev.ishubhamsingh.splashy.core.utils.initialiseLogging
21 | import org.koin.android.ext.koin.androidContext
22 | import org.koin.android.ext.koin.androidLogger
23 | import org.koin.core.context.startKoin
24 |
25 | class SplashyApp : Application() {
26 | companion object {
27 | lateinit var INSTANCE: SplashyApp
28 | }
29 |
30 | override fun onCreate() {
31 | super.onCreate()
32 | INSTANCE = this
33 | startKoin {
34 | androidContext(INSTANCE)
35 | androidLogger()
36 | modules(appModule())
37 | }
38 | initialiseLogging()
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/core/di/components/PlatformModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.di.components
17 |
18 | import dev.ishubhamsingh.splashy.core.utils.DatabaseDriverFactory
19 | import dev.ishubhamsingh.splashy.core.utils.FileUtils
20 | import org.koin.dsl.module
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | actual val platformModule = module {
24 | single { DatabaseDriverFactory(get()) }
25 | factory { FileUtils(get()) }
26 | }
27 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/core/presentation/SplashyTheme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.presentation
17 |
18 | import android.os.Build
19 | import androidx.compose.material3.MaterialTheme
20 | import androidx.compose.material3.dynamicDarkColorScheme
21 | import androidx.compose.material3.dynamicLightColorScheme
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.platform.LocalContext
24 | import dev.ishubhamsingh.splashy.ui.theme.DarkColors
25 | import dev.ishubhamsingh.splashy.ui.theme.LightColors
26 | import dev.ishubhamsingh.splashy.ui.theme.Shapes
27 | import dev.ishubhamsingh.splashy.ui.theme.getTypography
28 |
29 | @Composable
30 | actual fun SplashyTheme(
31 | darkTheme: Boolean,
32 | dynamicColor: Boolean,
33 | content: @Composable () -> Unit
34 | ) {
35 | val colorScheme =
36 | when {
37 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
38 | val context = LocalContext.current
39 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
40 | }
41 | darkTheme -> DarkColors
42 | else -> LightColors
43 | }
44 |
45 | MaterialTheme(
46 | colorScheme = colorScheme,
47 | typography = getTypography(),
48 | shapes = Shapes,
49 | content = content
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/core/utils/CommonUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import android.app.Activity
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.graphics.toArgb
22 | import androidx.compose.ui.platform.LocalContext
23 | import androidx.compose.ui.platform.LocalView
24 | import androidx.core.view.WindowCompat
25 | import dev.ishubhamsingh.splashy.BuildConfig
26 | import io.ktor.client.HttpClient
27 | import io.ktor.client.engine.okhttp.OkHttp
28 | import java.time.Duration
29 | import java.time.ZonedDateTime
30 | import java.time.format.DateTimeFormatter
31 |
32 | actual fun getHttpClient(): HttpClient {
33 | val httpClient =
34 | HttpClient(OkHttp) {
35 | engine {
36 | config {
37 | retryOnConnectionFailure(true)
38 | callTimeout(Duration.ofMinutes(0))
39 | connectTimeout(Duration.ofMinutes(0))
40 | readTimeout(Duration.ofMinutes(0))
41 | writeTimeout(Duration.ofMinutes(0))
42 | }
43 | }
44 | }
45 |
46 | return httpClient
47 | }
48 |
49 | actual fun getFormattedDateTime(timestamp: String, format: String): String {
50 | val date = ZonedDateTime.parse(timestamp)
51 | val formatter = DateTimeFormatter.ofPattern(format)
52 | return date.format(formatter)
53 | }
54 |
55 | actual fun getPlatform(): Platform = Platform.Android
56 |
57 | actual fun isDebug(): Boolean = BuildConfig.DEBUG
58 |
59 | @Composable
60 | actual fun getScreenHeight(): Int {
61 | return LocalContext.current.resources.displayMetrics.heightPixels
62 | }
63 |
64 | @Composable
65 | actual fun UpdateSystemBars(
66 | statusBarColor: Color,
67 | navigationBarColor: Color,
68 | isDarkTheme: Boolean
69 | ) {
70 | val view = LocalView.current
71 | val window = (view.context as? Activity)?.window ?: return
72 | window.statusBarColor = statusBarColor.toArgb()
73 | window.navigationBarColor = navigationBarColor.toArgb()
74 | WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isDarkTheme
75 | }
76 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/core/utils/DatabaseDriverFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import android.content.Context
19 | import app.cash.sqldelight.db.SqlDriver
20 | import app.cash.sqldelight.driver.android.AndroidSqliteDriver
21 | import dev.ishubhamsingh.splashy.db.SplashyDatabase
22 |
23 | /** Created by Shubham Singh on 11/08/23. */
24 | actual class DatabaseDriverFactory(private val context: Context) {
25 | actual fun createDriver(): SqlDriver {
26 | return AndroidSqliteDriver(schema = SplashyDatabase.Schema, context = context, name = DB_NAME)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/dev/ishubhamsingh/splashy/core/utils/FileUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import android.app.WallpaperManager
19 | import android.app.WallpaperManager.FLAG_LOCK
20 | import android.app.WallpaperManager.FLAG_SYSTEM
21 | import android.content.ContentValues
22 | import android.content.Context
23 | import android.content.Intent
24 | import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
25 | import android.graphics.Bitmap
26 | import android.graphics.BitmapFactory
27 | import android.net.Uri
28 | import android.os.Build
29 | import android.os.Environment
30 | import android.provider.MediaStore
31 | import android.widget.Toast
32 | import com.eygraber.uri.toAndroidUri
33 | import com.eygraber.uri.toUri
34 | import dev.ishubhamsingh.splashy.features.details.WallpaperScreenType
35 | import dev.ishubhamsingh.splashy.resources.Res
36 | import dev.ishubhamsingh.splashy.resources.applying_wallpaper_failed_message
37 | import dev.ishubhamsingh.splashy.resources.applying_wallpaper_success_message
38 | import dev.ishubhamsingh.splashy.resources.downloading_file_failed_message
39 | import dev.ishubhamsingh.splashy.resources.downloading_file_success_message
40 | import dev.ishubhamsingh.splashy.resources.opening_file_failed_message
41 | import dev.ishubhamsingh.splashy.resources.wallpaper_chooser_title
42 | import kotlin.coroutines.coroutineContext
43 | import kotlinx.coroutines.CoroutineScope
44 | import kotlinx.coroutines.Dispatchers
45 | import kotlinx.coroutines.launch
46 | import org.jetbrains.compose.resources.getString
47 |
48 | /** Created by Shubham Singh on 19/08/23. */
49 | actual class FileUtils(private val context: Context) {
50 |
51 | actual suspend fun saveByteArrayToFile(
52 | fileName: String,
53 | data: ByteArray,
54 | shouldOpenFile: Boolean,
55 | updateMessage: (String) -> Unit
56 | ) {
57 | var uri: Uri? = null
58 | var result = ""
59 |
60 | CoroutineScope(coroutineContext).launch(Dispatchers.IO) {
61 | runCatching {
62 | val imageBitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
63 |
64 | val mContentValues =
65 | ContentValues().apply {
66 | put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
67 | put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
68 | put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
69 | put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
70 | }
71 |
72 | context.contentResolver
73 | .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mContentValues)
74 | .apply {
75 | uri = this
76 | uri?.let {
77 | context.contentResolver.openOutputStream(it)?.let { outStream ->
78 | imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
79 | }
80 | }
81 | }
82 | }
83 | .onSuccess {
84 | if (shouldOpenFile) {
85 | openFile(uri?.toUri(), fileName)
86 | } else {
87 | result =
88 | getString(Res.string.downloading_file_success_message, Environment.DIRECTORY_PICTURES)
89 | updateMessage.invoke(result)
90 | }
91 | }
92 | .onFailure {
93 | result =
94 | if (shouldOpenFile) {
95 | getString(Res.string.opening_file_failed_message)
96 | } else {
97 | getString(Res.string.downloading_file_failed_message)
98 | }
99 | updateMessage.invoke(result)
100 | it.printStackTrace()
101 | }
102 | }
103 | }
104 |
105 | actual suspend fun openFile(uri: com.eygraber.uri.Uri?, fileName: String) {
106 | val intent = Intent(Intent.ACTION_ATTACH_DATA)
107 | intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
108 | intent.addCategory(Intent.CATEGORY_DEFAULT)
109 | intent.setDataAndType(uri?.toAndroidUri(), "image/jpeg")
110 | intent.putExtra("mimeType", "image/jpeg")
111 | val chooserIntent =
112 | Intent.createChooser(intent, getString(Res.string.wallpaper_chooser_title, fileName))
113 | chooserIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
114 | context.startActivity(chooserIntent)
115 | }
116 |
117 | actual suspend fun applyWallpaper(
118 | data: ByteArray,
119 | wallpaperScreenType: WallpaperScreenType,
120 | updateMessage: (String) -> Unit
121 | ) {
122 | val wallpaperManager = WallpaperManager.getInstance(context)
123 | var result = ""
124 | val flag =
125 | when (wallpaperScreenType) {
126 | WallpaperScreenType.HOME_SCREEN -> FLAG_SYSTEM
127 | WallpaperScreenType.LOCK_SCREEN -> FLAG_LOCK
128 | WallpaperScreenType.BOTH -> FLAG_SYSTEM or FLAG_LOCK
129 | else -> FLAG_SYSTEM
130 | }
131 |
132 | CoroutineScope(coroutineContext).launch(Dispatchers.Default) {
133 | runCatching {
134 | val imageBitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
135 | wallpaperManager.setBitmap(imageBitmap, null, true, flag)
136 | }
137 | .onSuccess {
138 | result = getString(Res.string.applying_wallpaper_success_message)
139 | updateMessage.invoke(result)
140 | }
141 | .onFailure {
142 | result = getString(Res.string.applying_wallpaper_failed_message)
143 | showMessage(result)
144 | updateMessage.invoke(result)
145 | }
146 | }
147 | }
148 |
149 | actual suspend fun shouldAskStorageRuntimePermission(): Boolean {
150 | return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
151 | }
152 |
153 | actual suspend fun showMessage(message: String) {
154 | CoroutineScope(coroutineContext).launch(Dispatchers.Main) {
155 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/values-v29/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Splashy
3 |
4 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/values/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/hat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/drawable/hat.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lato_black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lato_black.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lato_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lato_bold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lato_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lato_light.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lato_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lato_regular.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lato_thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lato_thin.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/lobster_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/composeApp/src/commonMain/composeResources/font/lobster_regular.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Splashy
3 | Filter by Categories
4 | Save to Gallery
5 | Download
6 | Set Wallpaper
7 | DETAILS
8 | Description:
9 | Posted on:
10 | Size:
11 | Likes:
12 | Color:
13 | Categories:
14 | Search
15 |
16 | Set Wallpaper
17 | Please select how you want to set the wallpaper
18 | Set using other app
19 | Set on Homescreen
20 | Set on Lockscreen
21 | Set on both screens
22 |
23 | Home
24 | Categories
25 | Favorites
26 | Photo Details
27 | Category Photos
28 | Settings
29 |
30 | Saved to gallery successfully
31 | Saving to gallery failed!
32 | Opening file failed!
33 | File saved successfully in %1$s
34 | Saving file failed!
35 | Wallpaper set successfully
36 | Setting wallpaper failed!
37 | Set %1$s as:
38 |
39 | Collections
40 | Categories
41 | %1$d Photos
42 |
43 | Select Theme
44 | Use Material You
45 | Apply wallpaper based colors
46 |
47 | - System
48 | - Light
49 | - Dark
50 |
51 | back
52 |
53 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/App.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy
17 |
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.runtime.LaunchedEffect
20 | import androidx.compose.runtime.mutableStateOf
21 | import cafe.adriel.voyager.navigator.Navigator
22 | import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
23 | import cafe.adriel.voyager.transitions.SlideTransition
24 | import dev.ishubhamsingh.splashy.core.navigation.TopLevelScreen
25 | import dev.ishubhamsingh.splashy.core.presentation.SplashyTheme
26 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
27 | import dev.ishubhamsingh.splashy.features.settings.Theme
28 | import org.koin.compose.koinInject
29 |
30 | val goBack = mutableStateOf(false)
31 | val selectedThemeState = mutableStateOf(Theme.SYSTEM.value)
32 | val isDarkThemeState = mutableStateOf(false)
33 | val isMaterialYouEnabledState = mutableStateOf(true)
34 |
35 | @Composable
36 | fun App(darkTheme: Boolean, dynamicColor: Boolean) {
37 |
38 | val settingsUtils = koinInject()
39 | LaunchedEffect(Unit) {
40 | selectedThemeState.value = settingsUtils.fetchInt(SettingsUtils.THEME, Theme.SYSTEM.value)
41 | isMaterialYouEnabledState.value =
42 | settingsUtils.fetchBoolean(SettingsUtils.IS_MATERIAL_YOU_ENABLED, true)
43 | }
44 |
45 | SplashyTheme(
46 | darkTheme = isDarkThemeState.value,
47 | dynamicColor = if (dynamicColor) isMaterialYouEnabledState.value else false
48 | ) {
49 | Navigator(
50 | screen = TopLevelScreen(),
51 | disposeBehavior =
52 | NavigatorDisposeBehavior(disposeNestedNavigators = false, disposeSteps = true)
53 | ) {
54 | SlideTransition(it)
55 | }
56 | }
57 |
58 | LaunchedEffect(selectedThemeState.value) {
59 | updateTheme(selectedThemeState.value, darkTheme) { isDarkTheme ->
60 | isDarkThemeState.value = isDarkTheme
61 | }
62 | }
63 | }
64 |
65 | fun updateTheme(theme: Int, isSystemDarkTheme: Boolean, onThemeChanged: (Boolean) -> Unit) {
66 | val isDarkTheme =
67 | if (theme == Theme.SYSTEM.value) {
68 | isSystemDarkTheme
69 | } else {
70 | theme == Theme.DARK.value
71 | }
72 | onThemeChanged(isDarkTheme)
73 | }
74 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/di/ApplicationModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.di
17 |
18 | import dev.ishubhamsingh.splashy.core.di.components.commonModule
19 | import dev.ishubhamsingh.splashy.core.di.components.platformModule
20 |
21 | fun appModule() = listOf(platformModule, commonModule)
22 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/di/components/CommonModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.di.components
17 |
18 | import dev.ishubhamsingh.splashy.core.domain.UnsplashRepository
19 | import dev.ishubhamsingh.splashy.core.network.UnsplashRepositoryImpl
20 | import dev.ishubhamsingh.splashy.core.network.api.UnsplashApi
21 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
22 | import dev.ishubhamsingh.splashy.core.utils.getHttpClient
23 | import dev.ishubhamsingh.splashy.db.createDatabase
24 | import dev.ishubhamsingh.splashy.features.categories.CategoriesScreenModel
25 | import dev.ishubhamsingh.splashy.features.categoriesPhotos.CategoriesPhotosScreenModel
26 | import dev.ishubhamsingh.splashy.features.favourites.FavouritesScreenModel
27 | import dev.ishubhamsingh.splashy.features.home.HomeScreenModel
28 | import dev.ishubhamsingh.splashy.features.settings.SettingsScreenModel
29 | import org.koin.core.module.dsl.singleOf
30 | import org.koin.dsl.module
31 |
32 | val commonModule = module {
33 | singleOf(::getHttpClient)
34 | single { UnsplashApi(get()) }
35 | single { createDatabase(get()) }
36 | factory { UnsplashRepositoryImpl(get(), get()) }
37 | factory { HomeScreenModel(get(), get()) }
38 | factory { FavouritesScreenModel(get(), get()) }
39 | factory { CategoriesScreenModel(get(), get()) }
40 | factory { CategoriesPhotosScreenModel(get(), get()) }
41 | factory { SettingsScreenModel(get()) }
42 | single { SettingsUtils() }
43 | }
44 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/di/components/PlatformModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.di.components
17 |
18 | import org.koin.core.module.Module
19 |
20 | /** Created by Shubham Singh on 11/08/23. */
21 | expect val platformModule: Module
22 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/domain/NetworkResult.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.domain
17 |
18 | sealed class NetworkResult(
19 | val data: T? = null,
20 | val message: String? = null,
21 | exception: Exception? = null
22 | ) {
23 | class Success(data: T?) : NetworkResult(data)
24 |
25 | class Error(message: String, exception: Exception? = null) :
26 | NetworkResult(message = message, exception = exception)
27 |
28 | class Loading(val isLoading: Boolean = true) : NetworkResult(null)
29 | }
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/domain/ScreenEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.domain
17 |
18 | /** Created by Shubham Singh on 12/08/23. */
19 | interface ScreenEvent
20 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/domain/UnsplashRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.domain
17 |
18 | import dev.ishubhamsingh.splashy.models.CollectionItem
19 | import dev.ishubhamsingh.splashy.models.DownloadUrl
20 | import dev.ishubhamsingh.splashy.models.Favourite
21 | import dev.ishubhamsingh.splashy.models.Photo
22 | import dev.ishubhamsingh.splashy.models.PhotoSearchCollection
23 | import dev.ishubhamsingh.splashy.models.Topic
24 | import kotlinx.coroutines.flow.Flow
25 |
26 | interface UnsplashRepository {
27 | fun getPhotos(page: Int, fetchFromRemote: Boolean = false): Flow>>
28 |
29 | fun searchPhotos(
30 | searchQuery: String,
31 | page: Int,
32 | fetchFromRemote: Boolean = false
33 | ): Flow>
34 |
35 | fun getPhotoDetails(id: String): Flow>
36 |
37 | fun getCollections(page: Int): Flow>>
38 |
39 | fun getCollectionById(id: String): Flow>
40 |
41 | fun getPhotosByCollection(id: String, page: Int): Flow>>
42 |
43 | fun getTopics(page: Int): Flow>>
44 |
45 | fun getTopicBySlug(slug: String): Flow>
46 |
47 | fun getPhotosByTopic(slug: String, page: Int): Flow>>
48 |
49 | fun getDownloadUrl(url: String): Flow>
50 |
51 | fun addFavourite(favourite: Favourite): Flow>
52 |
53 | fun removeFavourite(id: String): Flow>
54 |
55 | fun isFavourite(id: String): Flow>
56 |
57 | fun getFavourites(): Flow>>
58 | }
59 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/navigation/SplashyAppState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.navigation
17 |
18 | import androidx.compose.material3.SnackbarDuration
19 | import androidx.compose.material3.SnackbarHostState
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.runtime.remember
22 | import androidx.compose.runtime.rememberCoroutineScope
23 | import kotlinx.coroutines.CoroutineScope
24 | import kotlinx.coroutines.launch
25 |
26 | /** Created by Shubham Singh on 30/09/23. */
27 | data class SplashyAppState(
28 | val snackbarHostState: SnackbarHostState,
29 | val coroutineScope: CoroutineScope,
30 | ) {
31 |
32 | fun showSnackbar(message: String, duration: SnackbarDuration = SnackbarDuration.Short) {
33 | coroutineScope.launch { snackbarHostState.showSnackbar(message = message, duration = duration) }
34 | }
35 | }
36 |
37 | @Composable
38 | fun rememberSplashyAppState(
39 | snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
40 | coroutineScope: CoroutineScope = rememberCoroutineScope()
41 | ) =
42 | remember(snackbarHostState, coroutineScope) {
43 | SplashyAppState(snackbarHostState = snackbarHostState, coroutineScope = coroutineScope)
44 | }
45 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/network/KtorLogger.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.network
17 |
18 | import io.github.aakira.napier.Napier
19 | import io.ktor.client.plugins.logging.Logger
20 |
21 | /** Created by Shubham Singh on 05/08/23. */
22 | class KtorLogger() : Logger {
23 | override fun log(message: String) {
24 | Napier.d(message)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/presentation/SplashyTheme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.presentation
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import androidx.compose.runtime.Composable
20 |
21 | @Composable
22 | expect fun SplashyTheme(
23 | darkTheme: Boolean = isSystemInDarkTheme(),
24 | dynamicColor: Boolean,
25 | content: @Composable () -> Unit
26 | )
27 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/CommonUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.ui.graphics.Color
20 | import io.ktor.client.HttpClient
21 |
22 | expect fun getHttpClient(): HttpClient
23 |
24 | expect fun getFormattedDateTime(timestamp: String, format: String = "dd MMM yyyy, hh:mm a"): String
25 |
26 | expect fun getPlatform(): Platform
27 |
28 | expect fun isDebug(): Boolean
29 |
30 | @Composable expect fun getScreenHeight(): Int
31 |
32 | enum class Platform {
33 | Android,
34 | iOS
35 | }
36 |
37 | @Composable
38 | expect fun UpdateSystemBars(statusBarColor: Color, navigationBarColor: Color, isDarkTheme: Boolean)
39 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/DIHelper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import dev.ishubhamsingh.splashy.core.di.appModule
19 | import org.koin.core.context.startKoin
20 |
21 | fun initKoin() {
22 | startKoin { modules(appModule()) }
23 | }
24 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/DatabaseDriverFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import app.cash.sqldelight.db.SqlDriver
19 |
20 | /** Created by Shubham Singh on 11/08/23. */
21 | internal const val DB_NAME = "splashy.db"
22 |
23 | expect class DatabaseDriverFactory {
24 | fun createDriver(): SqlDriver
25 | }
26 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/Extensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import dev.ishubhamsingh.splashy.models.CollectionItem
19 | import kotlinx.datetime.Clock
20 | import kotlinx.datetime.Instant
21 | import kotlinx.datetime.LocalDateTime
22 | import kotlinx.datetime.TimeZone
23 | import kotlinx.datetime.toLocalDateTime
24 |
25 | inline fun > Int.toEnum(): T? {
26 | return enumValues().firstOrNull { it.ordinal == this }
27 | }
28 |
29 | fun ArrayList.getNonPremiumCollections(): ArrayList {
30 | val filteredList =
31 | this.filter { it.coverPhoto?.urls?.regular?.contains("plus.unsplash") == false }
32 | return ArrayList(filteredList)
33 | }
34 |
35 | // fun returns true if current device date is in between 22nd December and 5th January
36 | fun isChristmasNewYearWeek(): Boolean {
37 | val currentMoment: Instant = Clock.System.now()
38 | val datetimeInSystemZone: LocalDateTime =
39 | currentMoment.toLocalDateTime(TimeZone.currentSystemDefault())
40 | val currentMonth = datetimeInSystemZone.monthNumber
41 | val currentDay = datetimeInSystemZone.dayOfMonth
42 | return (currentMonth == 12 && currentDay >= 22) || (currentMonth == 1 && currentDay <= 5)
43 | }
44 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/FileUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import com.eygraber.uri.Uri
19 | import dev.ishubhamsingh.splashy.features.details.WallpaperScreenType
20 |
21 | /** Created by Shubham Singh on 19/08/23. */
22 | expect class FileUtils {
23 |
24 | suspend fun saveByteArrayToFile(
25 | fileName: String,
26 | data: ByteArray,
27 | shouldOpenFile: Boolean,
28 | updateMessage: (String) -> Unit = {}
29 | )
30 |
31 | suspend fun openFile(uri: Uri?, fileName: String)
32 |
33 | suspend fun applyWallpaper(
34 | data: ByteArray,
35 | wallpaperScreenType: WallpaperScreenType,
36 | updateMessage: (String) -> Unit = {}
37 | )
38 |
39 | suspend fun shouldAskStorageRuntimePermission(): Boolean
40 |
41 | suspend fun showMessage(message: String)
42 | }
43 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/Logging.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import io.github.aakira.napier.DebugAntilog
19 | import io.github.aakira.napier.Napier
20 |
21 | fun initialiseLogging() {
22 | if (isDebug()) {
23 | Napier.base(DebugAntilog())
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/core/utils/SettingsUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import com.russhwolf.settings.ObservableSettings
19 | import com.russhwolf.settings.Settings
20 | import dev.ishubhamsingh.splashy.features.settings.Theme
21 |
22 | /** Created by Shubham Singh on 24/11/23. */
23 | interface KeyValueStorage {
24 | fun storeInt(key: String, value: Int)
25 |
26 | fun storeBoolean(key: String, value: Boolean)
27 |
28 | fun storeFloat(key: String, value: Float)
29 |
30 | fun storeString(key: String, value: String)
31 |
32 | fun fetchString(key: String, default: String = ""): String
33 |
34 | fun fetchBoolean(key: String, default: Boolean): Boolean
35 |
36 | fun fetchInt(key: String, default: Int): Int
37 |
38 | fun fetchFloat(key: String, default: Float): Float
39 |
40 | fun clearStorage()
41 |
42 | fun removeKey(key: String)
43 | }
44 |
45 | class SettingsUtils(private val settings: Settings = Settings()) : KeyValueStorage {
46 |
47 | fun addListener(
48 | mSettings: ObservableSettings = settings as ObservableSettings,
49 | key: String,
50 | defaultValue: Int,
51 | callback: (Int?) -> Unit
52 | ) {
53 | mSettings.addIntListener(key, defaultValue) { newValue -> callback(newValue) }
54 | }
55 |
56 | override fun storeInt(key: String, value: Int) {
57 | settings.putInt(key, value)
58 | }
59 |
60 | override fun storeBoolean(key: String, value: Boolean) {
61 | settings.putBoolean(key, value)
62 | }
63 |
64 | override fun storeFloat(key: String, value: Float) {
65 | settings.putFloat(key, value)
66 | }
67 |
68 | override fun storeString(key: String, value: String) {
69 | settings.putString(key, value)
70 | }
71 |
72 | override fun fetchString(key: String, default: String): String {
73 | return settings.getString(key, default)
74 | }
75 |
76 | override fun fetchBoolean(key: String, default: Boolean): Boolean {
77 | return settings.getBoolean(key, default)
78 | }
79 |
80 | override fun fetchInt(key: String, default: Int): Int {
81 | return settings.getInt(key, default)
82 | }
83 |
84 | override fun fetchFloat(key: String, default: Float): Float {
85 | return settings.getFloat(key, default)
86 | }
87 |
88 | override fun clearStorage() {
89 | settings.clear()
90 | }
91 |
92 | override fun removeKey(key: String) {
93 | settings.remove(key)
94 | }
95 |
96 | companion object {
97 | const val THEME = "theme"
98 | const val IS_MATERIAL_YOU_ENABLED = "is_material_you_enabled"
99 | }
100 |
101 | fun isDarkTheme(isSystemDarkTheme: Boolean): Boolean {
102 | val currentTheme = fetchInt(THEME, Theme.SYSTEM.value)
103 |
104 | return if (currentTheme == Theme.SYSTEM.value) {
105 | isSystemDarkTheme
106 | } else {
107 | currentTheme == Theme.DARK.value
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/Database.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db
17 |
18 | import dev.ishubhamsingh.splashy.core.utils.DatabaseDriverFactory
19 | import dev.ishubhamsingh.splashy.db.columnAdapters.IntAdapter
20 | import dev.ishubhamsingh.splashy.db.columnAdapters.LinksAdapter
21 | import dev.ishubhamsingh.splashy.db.columnAdapters.TopicSubmissionsAdapter
22 | import dev.ishubhamsingh.splashy.db.columnAdapters.UrlsAdapter
23 | import dev.ishubhamsingh.splashy.db.columnAdapters.UserAdapter
24 |
25 | /** Created by Shubham Singh on 11/08/23. */
26 | fun createDatabase(databaseDriverFactory: DatabaseDriverFactory): SplashyDatabase {
27 | val driver = databaseDriverFactory.createDriver()
28 |
29 | return SplashyDatabase(
30 | driver = driver,
31 | photoEntityAdapter =
32 | PhotoEntity.Adapter(
33 | linksAdapter = LinksAdapter,
34 | topicSubmissionsAdapter = TopicSubmissionsAdapter,
35 | urlsAdapter = UrlsAdapter,
36 | userAdapter = UserAdapter,
37 | heightAdapter = IntAdapter,
38 | widthAdapter = IntAdapter,
39 | likesAdapter = IntAdapter
40 | ),
41 | favouriteEntityAdapter =
42 | FavouriteEntity.Adapter(topicSubmissionsAdapter = TopicSubmissionsAdapter)
43 | )
44 | }
45 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/columnAdapters/IntAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.columnAdapters
17 |
18 | import app.cash.sqldelight.ColumnAdapter
19 |
20 | /** Created by Shubham Singh on 11/08/23. */
21 | object IntAdapter : ColumnAdapter {
22 | override fun decode(databaseValue: Long): Int {
23 | return databaseValue.toInt()
24 | }
25 |
26 | override fun encode(value: Int): Long {
27 | return value.toLong()
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/columnAdapters/LinksAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.columnAdapters
17 |
18 | import app.cash.sqldelight.ColumnAdapter
19 | import dev.ishubhamsingh.splashy.models.Links
20 | import kotlinx.serialization.json.Json
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | object LinksAdapter : ColumnAdapter {
24 | override fun decode(databaseValue: String): Links {
25 | return Json.decodeFromString(databaseValue)
26 | }
27 |
28 | override fun encode(value: Links): String {
29 | return value.toString()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/columnAdapters/TopicSubmissionsAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.columnAdapters
17 |
18 | import app.cash.sqldelight.ColumnAdapter
19 | import dev.ishubhamsingh.splashy.models.TopicSubmissions
20 | import kotlinx.serialization.json.Json
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | object TopicSubmissionsAdapter : ColumnAdapter {
24 | override fun decode(databaseValue: String): TopicSubmissions {
25 | return Json.decodeFromString(databaseValue)
26 | }
27 |
28 | override fun encode(value: TopicSubmissions): String {
29 | return value.toString()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/columnAdapters/UrlsAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.columnAdapters
17 |
18 | import app.cash.sqldelight.ColumnAdapter
19 | import dev.ishubhamsingh.splashy.models.Urls
20 | import kotlinx.serialization.json.Json
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | object UrlsAdapter : ColumnAdapter {
24 | override fun decode(databaseValue: String): Urls {
25 | return Json.decodeFromString(databaseValue)
26 | }
27 |
28 | override fun encode(value: Urls): String {
29 | return value.toString()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/columnAdapters/UserAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.columnAdapters
17 |
18 | import app.cash.sqldelight.ColumnAdapter
19 | import dev.ishubhamsingh.splashy.models.User
20 | import kotlinx.serialization.json.Json
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | object UserAdapter : ColumnAdapter {
24 | override fun decode(databaseValue: String): User {
25 | return Json.decodeFromString(databaseValue)
26 | }
27 |
28 | override fun encode(value: User): String {
29 | return value.toString()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/mappers/FavouriteMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.mappers
17 |
18 | import dev.ishubhamsingh.splashy.db.FavouriteEntity
19 | import dev.ishubhamsingh.splashy.models.Favourite
20 | import dev.ishubhamsingh.splashy.models.Photo
21 |
22 | /** Created by Shubham Singh on 12/08/23. */
23 | fun Photo.toFavourite(): Favourite =
24 | Favourite(
25 | id = id,
26 | color = color,
27 | altDescription = altDescription,
28 | description = description,
29 | topicSubmissions = topicSubmissions,
30 | url = urls?.regular
31 | )
32 |
33 | fun Favourite.toFavouriteEntity(): FavouriteEntity =
34 | FavouriteEntity(
35 | id = id,
36 | color = color,
37 | altDescription = altDescription,
38 | description = description,
39 | topicSubmissions = topicSubmissions,
40 | url = url
41 | )
42 |
43 | fun FavouriteEntity.toFavourite(): Favourite =
44 | Favourite(
45 | id = id,
46 | color = color,
47 | altDescription = altDescription,
48 | description = description,
49 | topicSubmissions = topicSubmissions,
50 | url = url
51 | )
52 |
53 | fun List.toFavouriteList(): List = map { it.toFavourite() }
54 |
55 | fun List.toFavouriteArrayList(): ArrayList =
56 | ArrayList(toFavouriteList())
57 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/db/mappers/PhotoMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.db.mappers
17 |
18 | import dev.ishubhamsingh.splashy.db.PhotoEntity
19 | import dev.ishubhamsingh.splashy.models.Photo
20 | import dev.ishubhamsingh.splashy.models.PhotoSearchCollection
21 |
22 | /** Created by Shubham Singh on 11/08/23. */
23 | fun PhotoEntity.toPhoto(): Photo =
24 | Photo(
25 | id = id,
26 | altDescription = altDescription ?: "",
27 | color = color ?: "",
28 | description = description ?: "",
29 | width = width ?: 0,
30 | height = height ?: 0,
31 | likes = likes ?: 0,
32 | user = user,
33 | urls = urls,
34 | links = links,
35 | topicSubmissions = topicSubmissions,
36 | createdAt = createdAt,
37 | updatedAt = updatedAt,
38 | promotedAt = promotedAt
39 | )
40 |
41 | fun Photo.toPhotoEntity(): PhotoEntity =
42 | PhotoEntity(
43 | id = id,
44 | altDescription = altDescription,
45 | color = color,
46 | description = description,
47 | width = width,
48 | height = height,
49 | likes = likes,
50 | user = user,
51 | urls = urls,
52 | links = links,
53 | topicSubmissions = topicSubmissions,
54 | createdAt = createdAt,
55 | updatedAt = updatedAt,
56 | promotedAt = promotedAt
57 | )
58 |
59 | fun List.toPhotoList(): List = map { it.toPhoto() }
60 |
61 | fun List.toPhotoEntityList(): List = map { it.toPhotoEntity() }
62 |
63 | fun List.toPhotoArrayList(): ArrayList = ArrayList(toPhotoList())
64 |
65 | fun ArrayList.toPhotoSearchCollection(): PhotoSearchCollection =
66 | PhotoSearchCollection(results = this, total = this.size, totalPages = this.size / 10)
67 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/about/ui/AboutComponent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.about.ui
17 |
18 | class AboutComponent {}
19 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categories/CategoriesScreenModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categories
17 |
18 | import cafe.adriel.voyager.core.model.ScreenModel
19 | import cafe.adriel.voyager.core.model.screenModelScope
20 | import dev.ishubhamsingh.splashy.core.domain.NetworkResult
21 | import dev.ishubhamsingh.splashy.core.domain.UnsplashRepository
22 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
23 | import dev.ishubhamsingh.splashy.features.categories.ui.CategoriesEvent
24 | import dev.ishubhamsingh.splashy.features.categories.ui.CategoriesState
25 | import io.github.aakira.napier.Napier
26 | import kotlinx.coroutines.flow.MutableStateFlow
27 | import kotlinx.coroutines.flow.asStateFlow
28 | import kotlinx.coroutines.flow.update
29 | import kotlinx.coroutines.launch
30 |
31 | /** Created by Shubham Singh on 30/08/23. */
32 | class CategoriesScreenModel(
33 | private val unsplashRepository: UnsplashRepository,
34 | val settingsUtils: SettingsUtils
35 | ) : ScreenModel {
36 |
37 | private val _state = MutableStateFlow(CategoriesState())
38 | val state = _state.asStateFlow()
39 |
40 | init {
41 | onEvent(CategoriesEvent.Load)
42 | }
43 |
44 | fun onEvent(event: CategoriesEvent) {
45 | when (event) {
46 | CategoriesEvent.Refresh,
47 | CategoriesEvent.Load -> {
48 | fetchTopics()
49 | fetchCollections()
50 | }
51 | }
52 | }
53 |
54 | private fun fetchCollections() {
55 | screenModelScope.launch {
56 | unsplashRepository.getCollections(1).collect { networkResult ->
57 | when (networkResult) {
58 | is NetworkResult.Error -> {
59 | networkResult.message?.let {
60 | _state.update { categoriesState -> categoriesState.copy(networkError = it) }
61 | }
62 | Napier.e(networkResult.message.toString())
63 | }
64 | is NetworkResult.Loading -> {
65 | _state.update { detailsState ->
66 | detailsState.copy(isCollectionsLoading = networkResult.isLoading)
67 | }
68 | }
69 | is NetworkResult.Success -> {
70 | networkResult.data?.let {
71 | _state.update { categoriesState -> categoriesState.copy(collections = it) }
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
79 | private fun fetchTopics() {
80 | screenModelScope.launch {
81 | unsplashRepository.getTopics(1).collect { networkResult ->
82 | when (networkResult) {
83 | is NetworkResult.Error -> {
84 | networkResult.message?.let {
85 | _state.update { categoriesState -> categoriesState.copy(networkError = it) }
86 | }
87 | Napier.e(networkResult.message.toString())
88 | }
89 | is NetworkResult.Loading -> {
90 | _state.update { detailsState ->
91 | detailsState.copy(isTopicsLoading = networkResult.isLoading)
92 | }
93 | }
94 | is NetworkResult.Success -> {
95 | networkResult.data?.let {
96 | _state.update { categoriesState -> categoriesState.copy(topics = it) }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categories/ui/CategoriesEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categories.ui
17 |
18 | /** Created by Shubham Singh on 30/08/23. */
19 | sealed class CategoriesEvent {
20 | data object Refresh : CategoriesEvent()
21 |
22 | data object Load : CategoriesEvent()
23 | }
24 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categories/ui/CategoriesState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categories.ui
17 |
18 | import dev.ishubhamsingh.splashy.models.CollectionItem
19 | import dev.ishubhamsingh.splashy.models.Topic
20 |
21 | /** Created by Shubham Singh on 30/08/23. */
22 | data class CategoriesState(
23 | val isTopicsLoading: Boolean = false,
24 | val isCollectionsLoading: Boolean = false,
25 | val collections: ArrayList = arrayListOf(),
26 | val topics: ArrayList = arrayListOf(),
27 | val networkError: String? = null
28 | ) {
29 | val isCategoriesLoading: Boolean
30 | get() = isCollectionsLoading && isTopicsLoading
31 | }
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categoriesPhotos/ui/CategoriesPhotosEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categoriesPhotos.ui
17 |
18 | sealed class CategoriesPhotosEvent {
19 | data class Load(val id: String, val type: CategoryType) : CategoriesPhotosEvent()
20 |
21 | data object Refresh : CategoriesPhotosEvent()
22 |
23 | data object LoadMore : CategoriesPhotosEvent()
24 | }
25 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categoriesPhotos/ui/CategoriesPhotosScreen.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categoriesPhotos.ui
17 |
18 | import androidx.compose.foundation.clickable
19 | import androidx.compose.foundation.layout.Box
20 | import androidx.compose.foundation.layout.padding
21 | import androidx.compose.material3.ExperimentalMaterial3Api
22 | import androidx.compose.material3.Icon
23 | import androidx.compose.material3.MaterialTheme
24 | import androidx.compose.material3.Scaffold
25 | import androidx.compose.material3.Text
26 | import androidx.compose.material3.TopAppBar
27 | import androidx.compose.material3.TopAppBarDefaults
28 | import androidx.compose.runtime.Composable
29 | import androidx.compose.runtime.LaunchedEffect
30 | import androidx.compose.runtime.collectAsState
31 | import androidx.compose.runtime.getValue
32 | import androidx.compose.ui.Modifier
33 | import androidx.compose.ui.graphics.Color
34 | import androidx.compose.ui.text.style.TextOverflow
35 | import cafe.adriel.voyager.core.screen.Screen
36 | import cafe.adriel.voyager.koin.getScreenModel
37 | import cafe.adriel.voyager.navigator.LocalNavigator
38 | import cafe.adriel.voyager.navigator.currentOrThrow
39 | import compose.icons.EvaIcons
40 | import compose.icons.evaicons.Outline
41 | import compose.icons.evaicons.outline.ArrowIosBack
42 | import dev.ishubhamsingh.splashy.core.utils.UpdateSystemBars
43 | import dev.ishubhamsingh.splashy.core.utils.isChristmasNewYearWeek
44 | import dev.ishubhamsingh.splashy.features.categoriesPhotos.CategoriesPhotosScreenModel
45 | import dev.ishubhamsingh.splashy.features.details.ui.DetailsScreen
46 | import dev.ishubhamsingh.splashy.goBack
47 | import dev.ishubhamsingh.splashy.isDarkThemeState
48 | import dev.ishubhamsingh.splashy.models.Photo
49 | import dev.ishubhamsingh.splashy.ui.components.GoBack
50 | import dev.ishubhamsingh.splashy.ui.components.PhotoGridLayout
51 | import dev.ishubhamsingh.splashy.ui.components.SnowFallComponent
52 |
53 | data class CategoriesPhotosScreen(
54 | val id: String,
55 | val categoryType: CategoryType,
56 | val name: String
57 | ) : Screen {
58 |
59 | @OptIn(ExperimentalMaterial3Api::class)
60 | @Composable
61 | override fun Content() {
62 | val screenModel = getScreenModel()
63 | UpdateSystemBars(
64 | statusBarColor = Color.Transparent,
65 | navigationBarColor = Color.Transparent,
66 | isDarkTheme = isDarkThemeState.value
67 | )
68 | val navigator = LocalNavigator.currentOrThrow
69 | val state by screenModel.state.collectAsState()
70 |
71 | LaunchedEffect(Unit) { screenModel.onEvent(CategoriesPhotosEvent.Load(id, categoryType)) }
72 |
73 | Scaffold(
74 | topBar = {
75 | Box {
76 | TopAppBar(
77 | title = {
78 | Text(
79 | text = name,
80 | style = MaterialTheme.typography.titleLarge,
81 | maxLines = 1,
82 | overflow = TextOverflow.Ellipsis
83 | )
84 | },
85 | navigationIcon = {
86 | Icon(
87 | imageVector = EvaIcons.Outline.ArrowIosBack,
88 | contentDescription = "back",
89 | modifier = Modifier.clickable { navigator.pop() }
90 | )
91 | },
92 | colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent)
93 | )
94 | if (isChristmasNewYearWeek()) {
95 | SnowFallComponent()
96 | }
97 | }
98 | }
99 | ) { paddingValues ->
100 | PhotoGridLayout(
101 | isRefreshing = state.isRefreshing,
102 | onRefresh = { screenModel.onEvent(CategoriesPhotosEvent.Refresh) },
103 | onSurfaceTouch = {},
104 | isPaginating = state.isPaginating,
105 | photos = state.photos,
106 | onLoadMore = {
107 | if (state.totalPages > state.currentPage) {
108 | screenModel.onEvent(CategoriesPhotosEvent.LoadMore)
109 | }
110 | },
111 | onItemSelected = {
112 | photo: Photo?,
113 | id: String?,
114 | color: String?,
115 | url: String?,
116 | altDescription: String? ->
117 | navigator.push(
118 | DetailsScreen(
119 | photo = photo,
120 | id = id,
121 | color = color,
122 | url = url,
123 | altDescription = altDescription
124 | )
125 | )
126 | },
127 | error = state.networkError,
128 | shouldShowSearch = false,
129 | modifier = Modifier.padding(paddingValues)
130 | )
131 | }
132 |
133 | if (goBack.value) {
134 | GoBack(navigator)
135 | goBack.value = false
136 | }
137 | }
138 | }
139 |
140 | enum class CategoryType {
141 | COLLECTION,
142 | TOPIC
143 | }
144 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/categoriesPhotos/ui/CategoriesPhotosState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.categoriesPhotos.ui
17 |
18 | import dev.ishubhamsingh.splashy.models.CollectionItem
19 | import dev.ishubhamsingh.splashy.models.Photo
20 | import dev.ishubhamsingh.splashy.models.Topic
21 |
22 | data class CategoriesPhotosState(
23 | val id: String? = null,
24 | val isRefreshing: Boolean = false,
25 | val photos: ArrayList = arrayListOf(),
26 | val topic: Topic? = null,
27 | val collection: CollectionItem? = null,
28 | val networkError: String? = null,
29 | val isPaginating: Boolean = false,
30 | val currentPage: Int = 1,
31 | val totalPages: Int = 0,
32 | val categoryType: CategoryType? = null
33 | )
34 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/details/ui/DetailsEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.details.ui
17 |
18 | import dev.ishubhamsingh.splashy.core.domain.ScreenEvent
19 | import dev.ishubhamsingh.splashy.features.details.WallpaperScreenType
20 | import dev.ishubhamsingh.splashy.models.Photo
21 |
22 | sealed class DetailsEvent : ScreenEvent {
23 | data class LoadDetails(
24 | val photo: Photo?,
25 | val id: String?,
26 | val color: String?,
27 | val url: String?,
28 | val altDescription: String?
29 | ) : DetailsEvent()
30 |
31 | data object DownloadPhoto : DetailsEvent()
32 |
33 | data class ApplyAsWallpaper(val wallpaperScreenType: WallpaperScreenType) : DetailsEvent()
34 |
35 | data object ShowApplyWallpaperDialog : DetailsEvent()
36 |
37 | data object DismissApplyWallpaperDialog : DetailsEvent()
38 |
39 | data object AddFavourite : DetailsEvent()
40 |
41 | data object RemoveFavourite : DetailsEvent()
42 | }
43 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/details/ui/DetailsState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.details.ui
17 |
18 | import dev.ishubhamsingh.splashy.models.Photo
19 |
20 | data class DetailsState(
21 | val id: String? = null,
22 | val color: String? = null,
23 | val altDescription: String? = null,
24 | val url: String? = null,
25 | val photo: Photo? = null,
26 | val isFavourite: Boolean = false,
27 | val isLoading: Boolean = false,
28 | val isDownloading: Boolean = false,
29 | val isApplying: Boolean = false,
30 | val networkError: String? = null,
31 | val snackBarMessage: String? = null,
32 | val shouldShowApplyWallpaperDialog: Boolean = false,
33 | val downloadProgress: Int = 0
34 | )
35 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/favourites/FavouritesScreenModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.favourites
17 |
18 | import cafe.adriel.voyager.core.model.ScreenModel
19 | import cafe.adriel.voyager.core.model.screenModelScope
20 | import dev.ishubhamsingh.splashy.core.domain.NetworkResult
21 | import dev.ishubhamsingh.splashy.core.domain.UnsplashRepository
22 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
23 | import dev.ishubhamsingh.splashy.features.favourites.ui.FavouritesEvent
24 | import dev.ishubhamsingh.splashy.features.favourites.ui.FavouritesState
25 | import dev.ishubhamsingh.splashy.models.TopicFilter
26 | import dev.ishubhamsingh.splashy.models.TopicSubmissions
27 | import kotlinx.coroutines.Job
28 | import kotlinx.coroutines.flow.MutableStateFlow
29 | import kotlinx.coroutines.flow.asStateFlow
30 | import kotlinx.coroutines.flow.update
31 | import kotlinx.coroutines.launch
32 |
33 | /** Created by Shubham Singh on 12/08/23. */
34 | class FavouritesScreenModel(
35 | private val unsplashRepository: UnsplashRepository,
36 | val settingsUtils: SettingsUtils
37 | ) : ScreenModel {
38 |
39 | private val _state = MutableStateFlow(FavouritesState())
40 | val state = _state.asStateFlow()
41 |
42 | private var job: Job? = null
43 |
44 | fun onEvent(favouritesEvent: FavouritesEvent) {
45 | when (favouritesEvent) {
46 | is FavouritesEvent.Filter -> onFilterEvent(favouritesEvent.topic)
47 | FavouritesEvent.LoadFavourites -> fetchFavourites()
48 | FavouritesEvent.Refresh -> {
49 | _state.update { favouritesState ->
50 | favouritesState.copy(filterTopics = TopicSubmissions.TOPICS)
51 | }
52 | fetchFavourites()
53 | }
54 | }
55 | }
56 |
57 | private fun fetchFavourites() {
58 | cancelActiveJob()
59 | job =
60 | screenModelScope.launch {
61 | unsplashRepository.getFavourites().collect { result ->
62 | when (result) {
63 | is NetworkResult.Error -> {
64 | _state.update { favouritesState -> favouritesState.copy(error = result.message) }
65 | }
66 | is NetworkResult.Loading -> {
67 | _state.update { favouritesState ->
68 | favouritesState.copy(isRefreshing = result.isLoading)
69 | }
70 | }
71 | is NetworkResult.Success -> {
72 | result.data?.let {
73 | _state.update { favouritesState -> favouritesState.copy(favourites = it) }
74 | updateFilteredList(state.value.filterTopics)
75 | }
76 | }
77 | }
78 | }
79 | }
80 | }
81 |
82 | private fun onFilterEvent(topic: String) {
83 | val newFilterTopics =
84 | ArrayList(
85 | state.value.filterTopics.map {
86 | if (it.topic == topic) {
87 | TopicFilter(topic, !it.isSelected)
88 | } else {
89 | it
90 | }
91 | }
92 | )
93 |
94 | _state.update { favouritesState -> favouritesState.copy(filterTopics = newFilterTopics) }
95 |
96 | updateFilteredList(newFilterTopics)
97 | }
98 |
99 | private fun updateFilteredList(newFilterTopics: ArrayList) {
100 | val newFilteredFav =
101 | state.value.favourites.filter { fav ->
102 | fav.topicSubmissions?.containsAnyTopic(newFilterTopics) == true
103 | }
104 | _state.update { favouritesState ->
105 | favouritesState.copy(filteredFavourites = ArrayList(newFilteredFav))
106 | }
107 | }
108 |
109 | private fun cancelActiveJob() {
110 | if (job?.isActive == true) {
111 | job?.cancel()
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/favourites/ui/FavouritesEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.favourites.ui
17 |
18 | import dev.ishubhamsingh.splashy.core.domain.ScreenEvent
19 |
20 | /** Created by Shubham Singh on 12/08/23. */
21 | sealed class FavouritesEvent : ScreenEvent {
22 | data object LoadFavourites : FavouritesEvent()
23 |
24 | data class Filter(val topic: String) : FavouritesEvent()
25 |
26 | data object Refresh : FavouritesEvent()
27 | }
28 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/favourites/ui/FavouritesState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.favourites.ui
17 |
18 | import dev.ishubhamsingh.splashy.models.Favourite
19 | import dev.ishubhamsingh.splashy.models.TopicFilter
20 | import dev.ishubhamsingh.splashy.models.TopicSubmissions
21 |
22 | /** Created by Shubham Singh on 12/08/23. */
23 | data class FavouritesState(
24 | val favourites: ArrayList = arrayListOf(),
25 | val filterTopics: ArrayList = TopicSubmissions.TOPICS,
26 | val filteredFavourites: ArrayList = arrayListOf(),
27 | val isRefreshing: Boolean = false,
28 | val error: String? = null
29 | )
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/home/HomeScreenModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.home
17 |
18 | import cafe.adriel.voyager.core.model.ScreenModel
19 | import cafe.adriel.voyager.core.model.screenModelScope
20 | import dev.ishubhamsingh.splashy.core.domain.NetworkResult
21 | import dev.ishubhamsingh.splashy.core.domain.UnsplashRepository
22 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
23 | import dev.ishubhamsingh.splashy.features.home.ui.HomeEvent
24 | import dev.ishubhamsingh.splashy.features.home.ui.HomeState
25 | import kotlinx.coroutines.Dispatchers
26 | import kotlinx.coroutines.IO
27 | import kotlinx.coroutines.Job
28 | import kotlinx.coroutines.flow.MutableStateFlow
29 | import kotlinx.coroutines.flow.asStateFlow
30 | import kotlinx.coroutines.flow.update
31 | import kotlinx.coroutines.launch
32 |
33 | class HomeScreenModel(
34 | private val unsplashRepository: UnsplashRepository,
35 | val settingsUtils: SettingsUtils
36 | ) : ScreenModel {
37 |
38 | private val _state = MutableStateFlow(HomeState())
39 | val state = _state.asStateFlow()
40 |
41 | private var job: Job? = null
42 |
43 | init {
44 | onEvent(HomeEvent.Load)
45 | }
46 |
47 | fun onEvent(event: HomeEvent) {
48 | when (event) {
49 | HomeEvent.Load -> {
50 | getPhotosFromApi(forceFetch = true)
51 | }
52 | HomeEvent.Refresh -> {
53 | resetPage()
54 | getPhotosFromApi(forceFetch = true)
55 | }
56 | is HomeEvent.OnSearchQueryChange -> {
57 | _state.update { homeState -> homeState.copy(searchQuery = event.query) }
58 | resetPage(false)
59 | getPhotosFromApi(loadingType = LoadingType.SEARCH, forceFetch = true)
60 | }
61 | HomeEvent.LoadMore -> {
62 | nextPage()
63 | getPhotosFromApi(loadingType = LoadingType.PAGINATION, forceFetch = true)
64 | }
65 | }
66 | }
67 |
68 | private fun nextPage() {
69 | _state.update { it.copy(currentPage = it.currentPage + 1) }
70 | }
71 |
72 | private fun resetPage(isResetQuery: Boolean = true) {
73 | _state.update {
74 | if (isResetQuery) {
75 | it.copy(currentPage = 1, totalPages = 0, searchQuery = null, photos = arrayListOf())
76 | } else {
77 | it.copy(currentPage = 1, totalPages = 0, photos = arrayListOf())
78 | }
79 | }
80 | }
81 |
82 | private fun getPhotosFromApi(
83 | loadingType: LoadingType = LoadingType.REFRESH,
84 | forceFetch: Boolean = false
85 | ) {
86 | if (state.value.searchQuery.isNullOrEmpty().not()) {
87 | searchPhotos(loadingType = loadingType, forceFetch = forceFetch)
88 | } else {
89 | fetchPhotos(loadingType = loadingType, forceFetch = forceFetch)
90 | }
91 | }
92 |
93 | private fun searchPhotos(
94 | page: Int = state.value.currentPage,
95 | loadingType: LoadingType = LoadingType.REFRESH,
96 | forceFetch: Boolean = false
97 | ) {
98 | cancelActiveJob() // Cancel ongoing call before launching new
99 | job =
100 | screenModelScope.launch(Dispatchers.IO) {
101 | unsplashRepository
102 | .searchPhotos(
103 | if (state.value.searchQuery.isNullOrEmpty()) "wallpaper" else state.value.searchQuery!!,
104 | page,
105 | forceFetch
106 | )
107 | .collect { networkResult ->
108 | when (networkResult) {
109 | is NetworkResult.Success -> {
110 | networkResult.data?.let { resp ->
111 | _state.update { homeState ->
112 | val current = homeState.photos
113 | current.addAll(resp.results)
114 | homeState.copy(photos = current, totalPages = resp.totalPages)
115 | }
116 | }
117 | }
118 | is NetworkResult.Error -> {
119 | _state.update { homeState -> homeState.copy(networkError = networkResult.message) }
120 | }
121 | is NetworkResult.Loading -> {
122 | _state.update { homeState ->
123 | when (loadingType) {
124 | LoadingType.REFRESH -> homeState.copy(isRefreshing = networkResult.isLoading)
125 | LoadingType.PAGINATION -> homeState.copy(isPaginating = networkResult.isLoading)
126 | LoadingType.SEARCH -> homeState.copy(isSearching = networkResult.isLoading)
127 | }
128 | }
129 | }
130 | }
131 | }
132 | }
133 | }
134 |
135 | private fun fetchPhotos(
136 | page: Int = state.value.currentPage,
137 | loadingType: LoadingType = LoadingType.REFRESH,
138 | forceFetch: Boolean = false
139 | ) {
140 | cancelActiveJob() // Cancel ongoing call before launching new
141 | job =
142 | screenModelScope.launch(Dispatchers.IO) {
143 | unsplashRepository.getPhotos(page, forceFetch).collect { networkResult ->
144 | when (networkResult) {
145 | is NetworkResult.Success -> {
146 | networkResult.data?.let { resp ->
147 | _state.update { homeState ->
148 | val current = homeState.photos
149 | current.addAll(resp)
150 | homeState.copy(photos = current, totalPages = 1000)
151 | }
152 | }
153 | }
154 | is NetworkResult.Error -> {
155 | _state.update { homeState -> homeState.copy(networkError = networkResult.message) }
156 | }
157 | is NetworkResult.Loading -> {
158 | _state.update { homeState ->
159 | when (loadingType) {
160 | LoadingType.REFRESH -> homeState.copy(isRefreshing = networkResult.isLoading)
161 | LoadingType.PAGINATION -> homeState.copy(isPaginating = networkResult.isLoading)
162 | LoadingType.SEARCH -> homeState.copy(isSearching = networkResult.isLoading)
163 | }
164 | }
165 | }
166 | }
167 | }
168 | }
169 | }
170 |
171 | private fun cancelActiveJob() {
172 | if (job?.isActive == true) {
173 | job?.cancel()
174 | }
175 | }
176 | }
177 |
178 | enum class LoadingType {
179 | REFRESH,
180 | SEARCH,
181 | PAGINATION
182 | }
183 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/home/ui/HomeEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.home.ui
17 |
18 | import dev.ishubhamsingh.splashy.core.domain.ScreenEvent
19 |
20 | sealed class HomeEvent : ScreenEvent {
21 | data object Load : HomeEvent()
22 |
23 | data object Refresh : HomeEvent()
24 |
25 | data object LoadMore : HomeEvent()
26 |
27 | data class OnSearchQueryChange(val query: String?) : HomeEvent()
28 | }
29 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/home/ui/HomeState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.home.ui
17 |
18 | import dev.ishubhamsingh.splashy.models.Photo
19 |
20 | data class HomeState(
21 | val photos: ArrayList = arrayListOf(),
22 | val networkError: String? = null,
23 | val isRefreshing: Boolean = false,
24 | val isPaginating: Boolean = false,
25 | val isSearching: Boolean = false,
26 | val searchQuery: String? = null,
27 | val currentPage: Int = 1,
28 | val totalPages: Int = 0
29 | )
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/home/ui/HomeTab.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.home.ui
17 |
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.runtime.collectAsState
20 | import androidx.compose.runtime.getValue
21 | import androidx.compose.runtime.remember
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.graphics.vector.rememberVectorPainter
24 | import androidx.compose.ui.platform.LocalFocusManager
25 | import cafe.adriel.voyager.koin.getScreenModel
26 | import cafe.adriel.voyager.navigator.LocalNavigator
27 | import cafe.adriel.voyager.navigator.currentOrThrow
28 | import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
29 | import cafe.adriel.voyager.navigator.tab.Tab
30 | import cafe.adriel.voyager.navigator.tab.TabOptions
31 | import compose.icons.EvaIcons
32 | import compose.icons.evaicons.Fill
33 | import compose.icons.evaicons.Outline
34 | import compose.icons.evaicons.fill.Home
35 | import compose.icons.evaicons.outline.Home
36 | import dev.ishubhamsingh.splashy.core.utils.UpdateSystemBars
37 | import dev.ishubhamsingh.splashy.features.details.ui.DetailsScreen
38 | import dev.ishubhamsingh.splashy.features.home.HomeScreenModel
39 | import dev.ishubhamsingh.splashy.isDarkThemeState
40 | import dev.ishubhamsingh.splashy.models.Photo
41 | import dev.ishubhamsingh.splashy.resources.Res
42 | import dev.ishubhamsingh.splashy.resources.lbl_home
43 | import dev.ishubhamsingh.splashy.ui.components.PhotoGridLayout
44 | import org.jetbrains.compose.resources.stringResource
45 |
46 | /** Created by Shubham Singh on 29/09/23. */
47 | object HomeTab : Tab {
48 |
49 | override val options: TabOptions
50 | @Composable
51 | get() {
52 | val isSelected = LocalTabNavigator.current.current == this
53 | val title = stringResource(Res.string.lbl_home)
54 | val icon =
55 | rememberVectorPainter(if (isSelected) EvaIcons.Fill.Home else EvaIcons.Outline.Home)
56 |
57 | return remember { TabOptions(index = 0u, title, icon) }
58 | }
59 |
60 | @Composable
61 | override fun Content() {
62 | val screenModel = getScreenModel()
63 | UpdateSystemBars(
64 | statusBarColor = Color.Transparent,
65 | navigationBarColor = Color.Transparent,
66 | isDarkTheme = isDarkThemeState.value
67 | )
68 | val navigator = LocalNavigator.currentOrThrow.parent
69 | val state by screenModel.state.collectAsState()
70 | val focusManager = LocalFocusManager.current
71 |
72 | PhotoGridLayout(
73 | isRefreshing = state.isRefreshing,
74 | onRefresh = { screenModel.onEvent(HomeEvent.Refresh) },
75 | onSurfaceTouch = { focusManager.clearFocus() },
76 | searchQuery = state.searchQuery,
77 | isSearching = state.isSearching,
78 | onSearchQueryChange = { screenModel.onEvent(HomeEvent.OnSearchQueryChange(it)) },
79 | isPaginating = state.isPaginating,
80 | photos = state.photos,
81 | onLoadMore = {
82 | if (state.totalPages > state.currentPage) {
83 | screenModel.onEvent(HomeEvent.LoadMore)
84 | }
85 | },
86 | onItemSelected = {
87 | photo: Photo?,
88 | id: String?,
89 | color: String?,
90 | url: String?,
91 | altDescription: String? ->
92 | navigator?.push(
93 | DetailsScreen(
94 | photo = photo,
95 | id = id,
96 | color = color,
97 | url = url,
98 | altDescription = altDescription
99 | )
100 | )
101 | },
102 | error = state.networkError,
103 | shouldShowSearch = true
104 | )
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/settings/SettingsScreenModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.settings
17 |
18 | import cafe.adriel.voyager.core.model.ScreenModel
19 | import dev.ishubhamsingh.splashy.core.utils.SettingsUtils
20 | import dev.ishubhamsingh.splashy.features.settings.ui.SettingsEvent
21 | import dev.ishubhamsingh.splashy.features.settings.ui.SettingsState
22 | import dev.ishubhamsingh.splashy.isMaterialYouEnabledState
23 | import dev.ishubhamsingh.splashy.selectedThemeState
24 | import kotlinx.coroutines.flow.MutableStateFlow
25 | import kotlinx.coroutines.flow.asStateFlow
26 | import kotlinx.coroutines.flow.update
27 |
28 | /** Created by Shubham Singh on 24/11/23. */
29 | class SettingsScreenModel(val settingsUtils: SettingsUtils) : ScreenModel {
30 |
31 | private val _state = MutableStateFlow(SettingsState())
32 | val state = _state.asStateFlow()
33 |
34 | init {
35 | val currentTheme = settingsUtils.fetchInt(SettingsUtils.THEME, Theme.SYSTEM.value)
36 | val isMaterialYouEnabled =
37 | settingsUtils.fetchBoolean(SettingsUtils.IS_MATERIAL_YOU_ENABLED, true)
38 |
39 | _state.update {
40 | it.copy(selectedTheme = currentTheme, isMaterialYouEnabled = isMaterialYouEnabled)
41 | }
42 | }
43 |
44 | fun onEvent(event: SettingsEvent) {
45 | when (event) {
46 | is SettingsEvent.OnThemeChange -> {
47 | settingsUtils.storeInt(SettingsUtils.THEME, event.selectedTheme)
48 | _state.update {
49 | it.copy(
50 | selectedTheme = event.selectedTheme,
51 | )
52 | }
53 | selectedThemeState.value = event.selectedTheme
54 | }
55 | is SettingsEvent.OnMaterialYouToggle -> {
56 | settingsUtils.storeBoolean(
57 | SettingsUtils.IS_MATERIAL_YOU_ENABLED,
58 | event.isMaterialYouEnabled
59 | )
60 | _state.update {
61 | it.copy(
62 | isMaterialYouEnabled = event.isMaterialYouEnabled,
63 | )
64 | }
65 | isMaterialYouEnabledState.value = event.isMaterialYouEnabled
66 | }
67 | SettingsEvent.ShowThemeSelectionDialog -> {
68 | _state.update {
69 | it.copy(
70 | showThemeSelectionDialog = true,
71 | )
72 | }
73 | }
74 | SettingsEvent.HideThemeSelectionDialog -> {
75 | _state.update {
76 | it.copy(
77 | showThemeSelectionDialog = false,
78 | )
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
85 | enum class Theme(val value: Int) {
86 | LIGHT(0),
87 | DARK(1),
88 | SYSTEM(2)
89 | }
90 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/settings/ui/SettingsEvent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.settings.ui
17 |
18 | import dev.ishubhamsingh.splashy.core.domain.ScreenEvent
19 |
20 | /** Created by Shubham Singh on 24/11/23. */
21 | sealed class SettingsEvent : ScreenEvent {
22 | data class OnThemeChange(val selectedTheme: Int) : SettingsEvent()
23 |
24 | data class OnMaterialYouToggle(val isMaterialYouEnabled: Boolean) : SettingsEvent()
25 |
26 | data object ShowThemeSelectionDialog : SettingsEvent()
27 |
28 | data object HideThemeSelectionDialog : SettingsEvent()
29 | }
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/features/settings/ui/SettingsState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.features.settings.ui
17 |
18 | import dev.ishubhamsingh.splashy.features.settings.Theme
19 |
20 | /** Created by Shubham Singh on 24/11/23. */
21 | data class SettingsState(
22 | val selectedTheme: Int = Theme.SYSTEM.value,
23 | val isMaterialYouEnabled: Boolean = true,
24 | val showThemeSelectionDialog: Boolean = false
25 | )
26 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/CollectionItem.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.SerialName
19 | import kotlinx.serialization.Serializable
20 |
21 | @Serializable
22 | data class CollectionItem(
23 | @SerialName("cover_photo") val coverPhoto: CoverPhoto? = null,
24 | @SerialName("description") val description: String? = null,
25 | @SerialName("id") val id: String? = null,
26 | @SerialName("last_collected_at") val lastCollectedAt: String? = null,
27 | @SerialName("links") val links: Links? = null,
28 | @SerialName("private") val isPrivate: Boolean? = null,
29 | @SerialName("preview_photos") val previewPhotos: ArrayList? = null,
30 | @SerialName("published_at") val publishedAt: String? = null,
31 | @SerialName("share_key") val shareKey: String? = null,
32 | @SerialName("title") val title: String? = null,
33 | @SerialName("total_photos") val totalPhotos: Int? = null,
34 | @SerialName("updated_at") val updatedAt: String? = null,
35 | @SerialName("user") val user: User? = null
36 | ) {
37 | @Serializable
38 | data class CoverPhoto(
39 | @SerialName("blur_hash") val blurHash: String? = null,
40 | @SerialName("color") val color: String? = null,
41 | @SerialName("description") val description: String? = null,
42 | @SerialName("height") val height: Int? = null,
43 | @SerialName("id") val id: String? = null,
44 | @SerialName("liked_by_user") val likedByUser: Boolean? = null,
45 | @SerialName("likes") val likes: Int? = null,
46 | @SerialName("links") val links: Links? = null,
47 | @SerialName("urls") val urls: Urls? = null,
48 | @SerialName("user") val user: User? = null,
49 | @SerialName("width") val width: Int? = null
50 | ) {
51 | @Serializable
52 | data class Links(
53 | @SerialName("download") val download: String? = null,
54 | @SerialName("html") val html: String? = null,
55 | @SerialName("self") val self: String? = null
56 | )
57 |
58 | @Serializable
59 | data class Urls(
60 | @SerialName("full") val full: String? = null,
61 | @SerialName("raw") val raw: String? = null,
62 | @SerialName("regular") val regular: String? = null,
63 | @SerialName("small") val small: String? = null,
64 | @SerialName("thumb") val thumb: String? = null
65 | )
66 |
67 | @Serializable
68 | data class User(
69 | @SerialName("bio") val bio: String? = null,
70 | @SerialName("id") val id: String? = null,
71 | @SerialName("links") val links: Links? = null,
72 | @SerialName("location") val location: String? = null,
73 | @SerialName("name") val name: String? = null,
74 | @SerialName("portfolio_url") val portfolioUrl: String? = null,
75 | @SerialName("profile_image") val profileImage: ProfileImage? = null,
76 | @SerialName("total_collections") val totalCollections: Int? = null,
77 | @SerialName("total_likes") val totalLikes: Int? = null,
78 | @SerialName("total_photos") val totalPhotos: Int? = null,
79 | @SerialName("username") val username: String? = null
80 | ) {
81 | @Serializable
82 | data class Links(
83 | @SerialName("html") val html: String? = null,
84 | @SerialName("likes") val likes: String? = null,
85 | @SerialName("photos") val photos: String? = null,
86 | @SerialName("portfolio") val portfolio: String? = null,
87 | @SerialName("self") val self: String? = null
88 | )
89 |
90 | @Serializable
91 | data class ProfileImage(
92 | @SerialName("large") val large: String? = null,
93 | @SerialName("medium") val medium: String? = null,
94 | @SerialName("small") val small: String? = null
95 | )
96 | }
97 | }
98 |
99 | @Serializable
100 | data class Links(
101 | @SerialName("html") val html: String? = null,
102 | @SerialName("photos") val photos: String? = null,
103 | @SerialName("related") val related: String? = null,
104 | @SerialName("self") val self: String? = null
105 | )
106 |
107 | @Serializable
108 | data class User(
109 | @SerialName("bio") val bio: String? = null,
110 | @SerialName("id") val id: String? = null,
111 | @SerialName("links") val links: Links? = null,
112 | @SerialName("location") val location: String? = null,
113 | @SerialName("name") val name: String? = null,
114 | @SerialName("portfolio_url") val portfolioUrl: String? = null,
115 | @SerialName("profile_image") val profileImage: ProfileImage? = null,
116 | @SerialName("total_collections") val totalCollections: Int? = null,
117 | @SerialName("total_likes") val totalLikes: Int? = null,
118 | @SerialName("total_photos") val totalPhotos: Int? = null,
119 | @SerialName("updated_at") val updatedAt: String? = null,
120 | @SerialName("username") val username: String? = null
121 | ) {
122 | @Serializable
123 | data class Links(
124 | @SerialName("html") val html: String? = null,
125 | @SerialName("likes") val likes: String? = null,
126 | @SerialName("photos") val photos: String? = null,
127 | @SerialName("portfolio") val portfolio: String? = null,
128 | @SerialName("self") val self: String? = null
129 | )
130 |
131 | @Serializable
132 | data class ProfileImage(
133 | @SerialName("large") val large: String? = null,
134 | @SerialName("medium") val medium: String? = null,
135 | @SerialName("small") val small: String? = null
136 | )
137 | }
138 |
139 | @Serializable
140 | data class PreviewPhotos(
141 | @SerialName("blur_hash") val blurHash: String? = null,
142 | @SerialName("created_at") val createdAt: String? = null,
143 | @SerialName("id") val id: String? = null,
144 | @SerialName("slug") val slug: String? = null,
145 | @SerialName("updated_at") val updatedAt: String? = null,
146 | @SerialName("urls") val urls: Urls? = null
147 | ) {
148 | @Serializable
149 | data class Urls(
150 | @SerialName("full") val full: String? = null,
151 | @SerialName("raw") val raw: String? = null,
152 | @SerialName("regular") val regular: String? = null,
153 | @SerialName("small") val small: String? = null,
154 | @SerialName("small_s3") val smallS3: String? = null,
155 | @SerialName("thumb") val thumb: String? = null
156 | )
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/DownloadUrl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** Created by Shubham Singh on 20/08/23. */
21 | @Serializable data class DownloadUrl(val url: String)
22 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Favourite.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** Created by Shubham Singh on 12/08/23. */
21 | @Serializable
22 | data class Favourite(
23 | val id: String,
24 | val color: String?,
25 | val altDescription: String?,
26 | val description: String?,
27 | val topicSubmissions: TopicSubmissions?,
28 | val url: String?,
29 | )
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Links.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 | import kotlinx.serialization.encodeToString
22 | import kotlinx.serialization.json.Json
23 |
24 | @Serializable
25 | data class Links(
26 | @SerialName("download") val download: String = "",
27 | @SerialName("download_location") val downloadLocation: String = "",
28 | @SerialName("html") val html: String = "",
29 | @SerialName("self") val self: String = ""
30 | ) : JavaSerializable {
31 | override fun toString(): String {
32 | return Json.encodeToString(this)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/LinksX.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class LinksX(
24 | @SerialName("followers") val followers: String = "",
25 | @SerialName("following") val following: String = "",
26 | @SerialName("html") val html: String = "",
27 | @SerialName("likes") val likes: String = "",
28 | @SerialName("photos") val photos: String = "",
29 | @SerialName("portfolio") val portfolio: String = "",
30 | @SerialName("self") val self: String = ""
31 | ) : JavaSerializable
32 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Photo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class Photo(
24 | @SerialName("alt_description") val altDescription: String? = "",
25 | @SerialName("color") val color: String = "",
26 | @SerialName("created_at") val createdAt: String? = "",
27 | @SerialName("description") val description: String? = "",
28 | @SerialName("height") val height: Int = 0,
29 | @SerialName("id") val id: String = "",
30 | @SerialName("likes") val likes: Int = 0,
31 | @SerialName("links") val links: Links? = Links(),
32 | @SerialName("promoted_at") val promotedAt: String? = "",
33 | @SerialName("topic_submissions") val topicSubmissions: TopicSubmissions? = TopicSubmissions(),
34 | @SerialName("updated_at") val updatedAt: String? = "",
35 | @SerialName("urls") val urls: Urls? = Urls(),
36 | @SerialName("user") val user: User? = User(),
37 | @SerialName("width") val width: Int = 0
38 | ) : JavaSerializable
39 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/PhotoSearchCollection.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.SerialName
19 | import kotlinx.serialization.Serializable
20 |
21 | @Serializable
22 | data class PhotoSearchCollection(
23 | @SerialName("results") val results: ArrayList = arrayListOf(),
24 | @SerialName("total") val total: Int = 0,
25 | @SerialName("total_pages") val totalPages: Int = 0
26 | )
27 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/ProfileImage.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class ProfileImage(
24 | @SerialName("large") val large: String = "",
25 | @SerialName("medium") val medium: String = "",
26 | @SerialName("small") val small: String = ""
27 | ) : JavaSerializable
28 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Social.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class Social(
24 | @SerialName("instagram_username") val instagramUsername: String? = "",
25 | @SerialName("paypal_email") val paypalEmail: String? = null,
26 | @SerialName("portfolio_url") val portfolioUrl: String? = null,
27 | @SerialName("twitter_username") val twitterUsername: String? = null
28 | ) : JavaSerializable
29 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Sponsor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.SerialName
19 | import kotlinx.serialization.Serializable
20 |
21 | @Serializable
22 | data class Sponsor(
23 | @SerialName("accepted_tos") val acceptedTos: Boolean? = false,
24 | @SerialName("bio") val bio: String? = "",
25 | @SerialName("first_name") val firstName: String? = "",
26 | @SerialName("for_hire") val forHire: Boolean? = false,
27 | @SerialName("id") val id: String? = "",
28 | @SerialName("instagram_username") val instagramUsername: String? = "",
29 | @SerialName("last_name") val lastName: String? = null,
30 | @SerialName("links") val links: LinksX? = LinksX(),
31 | @SerialName("location") val location: String? = "",
32 | @SerialName("name") val name: String? = "",
33 | @SerialName("portfolio_url") val portfolioUrl: String? = "",
34 | @SerialName("profile_image") val profileImage: ProfileImage? = ProfileImage(),
35 | @SerialName("social") val social: Social? = Social(),
36 | @SerialName("total_collections") val totalCollections: Int? = 0,
37 | @SerialName("total_likes") val totalLikes: Int? = 0,
38 | @SerialName("total_photos") val totalPhotos: Int? = 0,
39 | @SerialName("twitter_username") val twitterUsername: String? = "",
40 | @SerialName("updated_at") val updatedAt: String? = "",
41 | @SerialName("username") val username: String? = ""
42 | )
43 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Sponsorship.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.SerialName
19 | import kotlinx.serialization.Serializable
20 |
21 | @Serializable
22 | data class Sponsorship(
23 | @SerialName("impression_urls") val impressionUrls: List = listOf(),
24 | @SerialName("sponsor") val sponsor: Sponsor = Sponsor(),
25 | @SerialName("tagline") val tagline: String = "",
26 | @SerialName("tagline_url") val taglineUrl: String = ""
27 | )
28 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/TopicFilter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** Created by Shubham Singh on 13/08/23. */
21 | @Serializable data class TopicFilter(val topic: String, val isSelected: Boolean = false)
22 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/TopicSubmissionStatus.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class TopicSubmissionStatus(
24 | @SerialName("approved_on") val approvedOn: String = "",
25 | @SerialName("status") val status: String = ""
26 | ) : JavaSerializable
27 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/TopicSubmissions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 | import kotlinx.serialization.encodeToString
22 | import kotlinx.serialization.json.Json
23 |
24 | @Serializable
25 | data class TopicSubmissions(
26 | @SerialName("architecture-interior") val architectureInterior: TopicSubmissionStatus? = null,
27 | @SerialName("experimental") val experimental: TopicSubmissionStatus? = null,
28 | @SerialName("fashion-beauty") val fashionBeauty: TopicSubmissionStatus? = null,
29 | @SerialName("street-photography") val streetPhotography: TopicSubmissionStatus? = null,
30 | @SerialName("wallpapers") val wallpapers: TopicSubmissionStatus? = null,
31 | @SerialName("travel") val travel: TopicSubmissionStatus? = null,
32 | @SerialName("arts-culture") val artsCulture: TopicSubmissionStatus? = null,
33 | @SerialName("athletics") val athletics: TopicSubmissionStatus? = null,
34 | @SerialName("color-of-water") val colorOfWater: TopicSubmissionStatus? = null,
35 | @SerialName("health") val health: TopicSubmissionStatus? = null,
36 | @SerialName("nature") val nature: TopicSubmissionStatus? = null,
37 | @SerialName("people") val people: TopicSubmissionStatus? = null,
38 | @SerialName("spirituality") val spirituality: TopicSubmissionStatus? = null,
39 | @SerialName("textures-patterns") val texturesPatterns: TopicSubmissionStatus? = null
40 | ) : JavaSerializable {
41 | private val topicSubmissionMap =
42 | hashMapOf(
43 | "Wallpapers" to wallpapers,
44 | "Experimental" to experimental,
45 | "Travel" to travel,
46 | "Fashion Beauty" to fashionBeauty,
47 | "Street Photography" to streetPhotography,
48 | "Architecture Interior" to architectureInterior,
49 | "Travel" to travel,
50 | "Arts Culture" to artsCulture,
51 | "Athletics" to athletics,
52 | "Color Of Water" to colorOfWater,
53 | "Health" to health,
54 | "Nature" to nature,
55 | "People" to people,
56 | "Spirituality" to spirituality,
57 | "Textures Patterns" to texturesPatterns
58 | )
59 |
60 | fun getApprovedTopics(): ArrayList {
61 | val approvedList = arrayListOf()
62 | topicSubmissionMap.entries.forEach { item ->
63 | item.let {
64 | if (it.value != null && it.value?.status == "approved") approvedList.add(item.key)
65 | }
66 | }
67 | return approvedList
68 | }
69 |
70 | override fun toString(): String {
71 | return Json.encodeToString(this)
72 | }
73 |
74 | fun containsAnyTopic(topicFilters: ArrayList): Boolean {
75 | if (topicFilters.any { it.isSelected }.not()) return true
76 |
77 | val selectedFilters: List =
78 | topicFilters.mapNotNull { if (it.isSelected) it.topic else null }
79 | return selectedFilters.any { getApprovedTopics().contains(it) }
80 | }
81 |
82 | companion object {
83 | val TOPICS = ArrayList(TopicSubmissions().topicSubmissionMap.keys.map { TopicFilter(it) })
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/Urls.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 | import kotlinx.serialization.encodeToString
22 | import kotlinx.serialization.json.Json
23 |
24 | @Serializable
25 | data class Urls(
26 | @SerialName("full") val full: String = "",
27 | @SerialName("raw") val raw: String = "",
28 | @SerialName("regular") val regular: String = "",
29 | @SerialName("small") val small: String = "",
30 | @SerialName("small_s3") val smallS3: String = "",
31 | @SerialName("thumb") val thumb: String = ""
32 | ) : JavaSerializable {
33 | override fun toString(): String {
34 | return Json.encodeToString(this)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/models/User.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.models
17 |
18 | import cafe.adriel.voyager.core.lifecycle.JavaSerializable
19 | import kotlinx.serialization.SerialName
20 | import kotlinx.serialization.Serializable
21 | import kotlinx.serialization.encodeToString
22 | import kotlinx.serialization.json.Json
23 |
24 | @Serializable
25 | data class User(
26 | @SerialName("accepted_tos") val acceptedTos: Boolean? = false,
27 | @SerialName("bio") val bio: String? = "",
28 | @SerialName("first_name") val firstName: String? = "",
29 | @SerialName("for_hire") val forHire: Boolean? = false,
30 | @SerialName("id") val id: String? = "",
31 | @SerialName("instagram_username") val instagramUsername: String? = "",
32 | @SerialName("last_name") val lastName: String? = "",
33 | @SerialName("links") val links: LinksX? = LinksX(),
34 | @SerialName("location") val location: String? = "",
35 | @SerialName("name") val name: String? = "",
36 | @SerialName("portfolio_url") val portfolioUrl: String? = "",
37 | @SerialName("profile_image") val profileImage: ProfileImage? = ProfileImage(),
38 | @SerialName("social") val social: Social? = Social(),
39 | @SerialName("total_collections") val totalCollections: Int? = 0,
40 | @SerialName("total_likes") val totalLikes: Int? = 0,
41 | @SerialName("total_photos") val totalPhotos: Int? = 0,
42 | @SerialName("twitter_username") val twitterUsername: String? = "",
43 | @SerialName("updated_at") val updatedAt: String? = "",
44 | @SerialName("username") val username: String? = ""
45 | ) : JavaSerializable {
46 | override fun toString(): String {
47 | return Json.encodeToString(this)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.ui.theme
17 |
18 | import androidx.compose.ui.graphics.Color
19 |
20 | val md_theme_light_primary = Color(0xFF006C45)
21 | val md_theme_light_onPrimary = Color(0xFFFFFFFF)
22 | val md_theme_light_primaryContainer = Color(0xFF8FF7BF)
23 | val md_theme_light_onPrimaryContainer = Color(0xFF002112)
24 | val md_theme_light_secondary = Color(0xFF4E6355)
25 | val md_theme_light_onSecondary = Color(0xFFFFFFFF)
26 | val md_theme_light_secondaryContainer = Color(0xFFD0E8D7)
27 | val md_theme_light_onSecondaryContainer = Color(0xFF0B1F15)
28 | val md_theme_light_tertiary = Color(0xFF3C6472)
29 | val md_theme_light_onTertiary = Color(0xFFFFFFFF)
30 | val md_theme_light_tertiaryContainer = Color(0xFFBFE9F9)
31 | val md_theme_light_onTertiaryContainer = Color(0xFF001F28)
32 | val md_theme_light_error = Color(0xFFBA1A1A)
33 | val md_theme_light_errorContainer = Color(0xFFFFDAD6)
34 | val md_theme_light_onError = Color(0xFFFFFFFF)
35 | val md_theme_light_onErrorContainer = Color(0xFF410002)
36 | val md_theme_light_background = Color(0xFFFBFDF8)
37 | val md_theme_light_onBackground = Color(0xFF191C1A)
38 | val md_theme_light_surface = Color(0xFFFBFDF8)
39 | val md_theme_light_onSurface = Color(0xFF191C1A)
40 | val md_theme_light_surfaceVariant = Color(0xFFDCE5DC)
41 | val md_theme_light_onSurfaceVariant = Color(0xFF404943)
42 | val md_theme_light_outline = Color(0xFF707972)
43 | val md_theme_light_inverseOnSurface = Color(0xFFEFF1ED)
44 | val md_theme_light_inverseSurface = Color(0xFF2E312E)
45 | val md_theme_light_inversePrimary = Color(0xFF73DAA4)
46 | val md_theme_light_shadow = Color(0xFF000000)
47 | val md_theme_light_surfaceTint = Color(0xFF006C45)
48 | val md_theme_light_outlineVariant = Color(0xFFC0C9C1)
49 | val md_theme_light_scrim = Color(0xFF000000)
50 |
51 | val md_theme_dark_primary = Color(0xFF73DAA4)
52 | val md_theme_dark_onPrimary = Color(0xFF003822)
53 | val md_theme_dark_primaryContainer = Color(0xFF005233)
54 | val md_theme_dark_onPrimaryContainer = Color(0xFF8FF7BF)
55 | val md_theme_dark_secondary = Color(0xFFB4CCBB)
56 | val md_theme_dark_onSecondary = Color(0xFF203529)
57 | val md_theme_dark_secondaryContainer = Color(0xFF364B3F)
58 | val md_theme_dark_onSecondaryContainer = Color(0xFFD0E8D7)
59 | val md_theme_dark_tertiary = Color(0xFFA4CDDD)
60 | val md_theme_dark_onTertiary = Color(0xFF053542)
61 | val md_theme_dark_tertiaryContainer = Color(0xFF234C59)
62 | val md_theme_dark_onTertiaryContainer = Color(0xFFBFE9F9)
63 | val md_theme_dark_error = Color(0xFFFFB4AB)
64 | val md_theme_dark_errorContainer = Color(0xFF93000A)
65 | val md_theme_dark_onError = Color(0xFF690005)
66 | val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
67 | val md_theme_dark_background = Color(0xFF191C1A)
68 | val md_theme_dark_onBackground = Color(0xFFE1E3DF)
69 | val md_theme_dark_surface = Color(0xFF191C1A)
70 | val md_theme_dark_onSurface = Color(0xFFE1E3DF)
71 | val md_theme_dark_surfaceVariant = Color(0xFF404943)
72 | val md_theme_dark_onSurfaceVariant = Color(0xFFC0C9C1)
73 | val md_theme_dark_outline = Color(0xFF8A938B)
74 | val md_theme_dark_inverseOnSurface = Color(0xFF191C1A)
75 | val md_theme_dark_inverseSurface = Color(0xFFE1E3DF)
76 | val md_theme_dark_inversePrimary = Color(0xFF006C45)
77 | val md_theme_dark_shadow = Color(0xFF000000)
78 | val md_theme_dark_surfaceTint = Color(0xFF73DAA4)
79 | val md_theme_dark_outlineVariant = Color(0xFF404943)
80 | val md_theme_dark_scrim = Color(0xFF000000)
81 |
82 | val seed = Color(0xFF246A49)
83 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.ui.theme
17 |
18 | import androidx.compose.foundation.shape.RoundedCornerShape
19 | import androidx.compose.material3.Shapes
20 | import androidx.compose.material3.darkColorScheme
21 | import androidx.compose.material3.lightColorScheme
22 | import androidx.compose.ui.unit.dp
23 |
24 | val LightColors =
25 | lightColorScheme(
26 | primary = md_theme_light_primary,
27 | onPrimary = md_theme_light_onPrimary,
28 | primaryContainer = md_theme_light_primaryContainer,
29 | onPrimaryContainer = md_theme_light_onPrimaryContainer,
30 | secondary = md_theme_light_secondary,
31 | onSecondary = md_theme_light_onSecondary,
32 | secondaryContainer = md_theme_light_secondaryContainer,
33 | onSecondaryContainer = md_theme_light_onSecondaryContainer,
34 | tertiary = md_theme_light_tertiary,
35 | onTertiary = md_theme_light_onTertiary,
36 | tertiaryContainer = md_theme_light_tertiaryContainer,
37 | onTertiaryContainer = md_theme_light_onTertiaryContainer,
38 | error = md_theme_light_error,
39 | errorContainer = md_theme_light_errorContainer,
40 | onError = md_theme_light_onError,
41 | onErrorContainer = md_theme_light_onErrorContainer,
42 | background = md_theme_light_background,
43 | onBackground = md_theme_light_onBackground,
44 | surface = md_theme_light_surface,
45 | onSurface = md_theme_light_onSurface,
46 | surfaceVariant = md_theme_light_surfaceVariant,
47 | onSurfaceVariant = md_theme_light_onSurfaceVariant,
48 | outline = md_theme_light_outline,
49 | inverseOnSurface = md_theme_light_inverseOnSurface,
50 | inverseSurface = md_theme_light_inverseSurface,
51 | inversePrimary = md_theme_light_inversePrimary,
52 | surfaceTint = md_theme_light_surfaceTint,
53 | outlineVariant = md_theme_light_outlineVariant,
54 | scrim = md_theme_light_scrim,
55 | )
56 |
57 | val DarkColors =
58 | darkColorScheme(
59 | primary = md_theme_dark_primary,
60 | onPrimary = md_theme_dark_onPrimary,
61 | primaryContainer = md_theme_dark_primaryContainer,
62 | onPrimaryContainer = md_theme_dark_onPrimaryContainer,
63 | secondary = md_theme_dark_secondary,
64 | onSecondary = md_theme_dark_onSecondary,
65 | secondaryContainer = md_theme_dark_secondaryContainer,
66 | onSecondaryContainer = md_theme_dark_onSecondaryContainer,
67 | tertiary = md_theme_dark_tertiary,
68 | onTertiary = md_theme_dark_onTertiary,
69 | tertiaryContainer = md_theme_dark_tertiaryContainer,
70 | onTertiaryContainer = md_theme_dark_onTertiaryContainer,
71 | error = md_theme_dark_error,
72 | errorContainer = md_theme_dark_errorContainer,
73 | onError = md_theme_dark_onError,
74 | onErrorContainer = md_theme_dark_onErrorContainer,
75 | background = md_theme_dark_background,
76 | onBackground = md_theme_dark_onBackground,
77 | surface = md_theme_dark_surface,
78 | onSurface = md_theme_dark_onSurface,
79 | surfaceVariant = md_theme_dark_surfaceVariant,
80 | onSurfaceVariant = md_theme_dark_onSurfaceVariant,
81 | outline = md_theme_dark_outline,
82 | inverseOnSurface = md_theme_dark_inverseOnSurface,
83 | inverseSurface = md_theme_dark_inverseSurface,
84 | inversePrimary = md_theme_dark_inversePrimary,
85 | surfaceTint = md_theme_dark_surfaceTint,
86 | outlineVariant = md_theme_dark_outlineVariant,
87 | scrim = md_theme_dark_scrim,
88 | )
89 |
90 | val Shapes =
91 | Shapes(
92 | extraSmall = RoundedCornerShape(2.dp),
93 | small = RoundedCornerShape(4.dp),
94 | medium = RoundedCornerShape(8.dp),
95 | large = RoundedCornerShape(16.dp),
96 | extraLarge = RoundedCornerShape(32.dp)
97 | )
98 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/dev/ishubhamsingh/splashy/ui/theme/Typography.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.ui.theme
17 |
18 | import androidx.compose.material3.Typography
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.text.TextStyle
21 | import androidx.compose.ui.text.font.FontFamily
22 | import androidx.compose.ui.text.font.FontStyle
23 | import androidx.compose.ui.text.font.FontWeight
24 | import androidx.compose.ui.unit.sp
25 | import dev.ishubhamsingh.splashy.resources.Res
26 | import dev.ishubhamsingh.splashy.resources.lato_black
27 | import dev.ishubhamsingh.splashy.resources.lato_bold
28 | import dev.ishubhamsingh.splashy.resources.lato_light
29 | import dev.ishubhamsingh.splashy.resources.lato_regular
30 | import dev.ishubhamsingh.splashy.resources.lato_thin
31 | import dev.ishubhamsingh.splashy.resources.lobster_regular
32 | import org.jetbrains.compose.resources.Font
33 |
34 | @Composable
35 | fun getLatoRegular() =
36 | FontFamily(
37 | Font(resource = Res.font.lato_regular, weight = FontWeight.Normal, style = FontStyle.Normal)
38 | )
39 |
40 | @Composable
41 | fun getLatoBold() = FontFamily(Font(Res.font.lato_bold, FontWeight.Bold, FontStyle.Normal))
42 |
43 | @Composable
44 | fun getLatoBlack() = FontFamily(Font(Res.font.lato_black, FontWeight.Black, FontStyle.Normal))
45 |
46 | @Composable
47 | fun getLatoThin() = FontFamily(Font(Res.font.lato_thin, FontWeight.Thin, FontStyle.Normal))
48 |
49 | @Composable
50 | fun getLatoLight() = FontFamily(Font(Res.font.lato_light, FontWeight.Light, FontStyle.Normal))
51 |
52 | @Composable
53 | fun getLobsterRegular() =
54 | FontFamily(Font(Res.font.lobster_regular, FontWeight.Normal, FontStyle.Normal))
55 |
56 | @Composable
57 | fun getTypography(): Typography {
58 |
59 | val latoBlack = getLatoBlack()
60 | val latoBold = getLatoBold()
61 | val latoRegular = getLatoRegular()
62 | val latoThin = getLatoThin()
63 | val latoLight = getLatoLight()
64 |
65 | return Typography(
66 | displayLarge =
67 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 52.sp),
68 | displayMedium =
69 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 24.sp),
70 | displaySmall =
71 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 18.sp),
72 | headlineLarge =
73 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 24.sp),
74 | headlineMedium =
75 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 18.sp),
76 | headlineSmall =
77 | TextStyle(fontFamily = latoBlack, fontWeight = FontWeight.Black, fontSize = 16.sp),
78 | titleLarge = TextStyle(fontFamily = latoBold, fontWeight = FontWeight.Bold, fontSize = 24.sp),
79 | titleMedium = TextStyle(fontFamily = latoBold, fontWeight = FontWeight.Bold, fontSize = 18.sp),
80 | titleSmall = TextStyle(fontFamily = latoBold, fontWeight = FontWeight.Bold, fontSize = 16.sp),
81 | bodyLarge =
82 | TextStyle(fontFamily = latoRegular, fontWeight = FontWeight.Normal, fontSize = 24.sp),
83 | bodyMedium =
84 | TextStyle(fontFamily = latoRegular, fontWeight = FontWeight.Normal, fontSize = 18.sp),
85 | bodySmall =
86 | TextStyle(fontFamily = latoRegular, fontWeight = FontWeight.Normal, fontSize = 16.sp),
87 | labelLarge = TextStyle(fontFamily = latoLight, fontWeight = FontWeight.Light, fontSize = 18.sp),
88 | labelMedium =
89 | TextStyle(fontFamily = latoLight, fontWeight = FontWeight.Light, fontSize = 16.sp),
90 | labelSmall = TextStyle(fontFamily = latoLight, fontWeight = FontWeight.Light, fontSize = 14.sp)
91 | )
92 | }
93 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/sqldelight/dev/ishubhamsingh/splashy/db/Favourite.sq:
--------------------------------------------------------------------------------
1 | import dev.ishubhamsingh.splashy.models.TopicSubmissions;
2 |
3 | CREATE TABLE favouriteEntity (
4 | id TEXT NOT NULL UNIQUE PRIMARY KEY,
5 | color TEXT,
6 | altDescription TEXT,
7 | description TEXT,
8 | topicSubmissions TEXT AS TopicSubmissions,
9 | url TEXT
10 | );
11 |
12 | getFavourites:
13 | SELECT *
14 | FROM favouriteEntity;
15 |
16 | getFavouritesById:
17 | SELECT *
18 | FROM favouriteEntity
19 | WHERE id = :id;
20 |
21 | deleteFavourite:
22 | DELETE FROM favouriteEntity
23 | WHERE id = :id;
24 |
25 | deleteAllFavourites:
26 | DELETE FROM favouriteEntity;
27 |
28 | insertFavourite:
29 | INSERT OR REPLACE
30 | INTO favouriteEntity(
31 | id,
32 | color,
33 | altDescription,
34 | description,
35 | topicSubmissions,
36 | url
37 | ) VALUES ?;
--------------------------------------------------------------------------------
/composeApp/src/commonMain/sqldelight/dev/ishubhamsingh/splashy/db/Photo.sq:
--------------------------------------------------------------------------------
1 | import dev.ishubhamsingh.splashy.models.Links;
2 | import dev.ishubhamsingh.splashy.models.TopicSubmissions;
3 | import dev.ishubhamsingh.splashy.models.Urls;
4 | import dev.ishubhamsingh.splashy.models.User;
5 | import kotlin.Int;
6 |
7 | CREATE TABLE photoEntity (
8 | id TEXT NOT NULL UNIQUE PRIMARY KEY,
9 | color TEXT,
10 | altDescription TEXT,
11 | description TEXT,
12 | likes INTEGER AS Int,
13 | width INTEGER AS Int,
14 | height INTEGER AS Int,
15 | links TEXT AS Links,
16 | topicSubmissions TEXT AS TopicSubmissions,
17 | urls TEXT AS Urls,
18 | user TEXT AS User,
19 | promotedAt TEXT,
20 | updatedAt TEXT,
21 | createdAt TEXT
22 | );
23 |
24 | getPhotos:
25 | SELECT *
26 | FROM photoEntity;
27 |
28 | getPhotosById:
29 | SELECT *
30 | FROM photoEntity
31 | WHERE id = :id;
32 |
33 | deletePhoto:
34 | DELETE FROM photoEntity
35 | WHERE id = :id;
36 |
37 | deleteAllPhotos:
38 | DELETE FROM photoEntity;
39 |
40 | insertPhoto:
41 | INSERT OR REPLACE
42 | INTO photoEntity(
43 | id,
44 | color,
45 | altDescription,
46 | description,
47 | likes,
48 | width,
49 | height,
50 | links,
51 | topicSubmissions,
52 | urls,
53 | user,
54 | promotedAt,
55 | updatedAt,
56 | createdAt
57 | ) VALUES ?;
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/App.ios.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import com.moriatsushi.insetsx.WindowInsetsUIViewController
20 | import platform.UIKit.UIViewController
21 |
22 | fun MainViewController(): UIViewController {
23 | return WindowInsetsUIViewController {
24 | App(darkTheme = isSystemInDarkTheme(), dynamicColor = false)
25 | }
26 | }
27 |
28 | fun OnBackGesture() {
29 | goBack.value = true
30 | }
31 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/core/di.components/PlatformModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.di.components
17 |
18 | import dev.ishubhamsingh.splashy.core.utils.DatabaseDriverFactory
19 | import dev.ishubhamsingh.splashy.core.utils.FileUtils
20 | import org.koin.dsl.module
21 |
22 | actual val platformModule = module {
23 | single { DatabaseDriverFactory() }
24 | factory { FileUtils() }
25 | }
26 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/core/presentation/SplashyTheme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.presentation
17 |
18 | import androidx.compose.material3.MaterialTheme
19 | import androidx.compose.runtime.Composable
20 | import dev.ishubhamsingh.splashy.ui.theme.DarkColors
21 | import dev.ishubhamsingh.splashy.ui.theme.LightColors
22 | import dev.ishubhamsingh.splashy.ui.theme.Shapes
23 | import dev.ishubhamsingh.splashy.ui.theme.getTypography
24 |
25 | @Composable
26 | actual fun SplashyTheme(
27 | darkTheme: Boolean,
28 | dynamicColor: Boolean,
29 | content: @Composable () -> Unit
30 | ) {
31 | MaterialTheme(
32 | colorScheme = if (darkTheme) DarkColors else LightColors,
33 | typography = getTypography(),
34 | shapes = Shapes,
35 | content = content
36 | )
37 | }
38 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/core/utils/CommonUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.ui.ExperimentalComposeUiApi
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.platform.LocalWindowInfo
22 | import androidx.compose.ui.text.font.Font
23 | import io.ktor.client.HttpClient
24 | import io.ktor.client.engine.darwin.Darwin
25 | import kotlin.experimental.ExperimentalNativeApi
26 | import kotlin.native.Platform as NativePlatform
27 | import platform.Foundation.NSDateFormatter
28 | import platform.Foundation.NSISO8601DateFormatter
29 | import platform.Foundation.NSLocale
30 | import platform.Foundation.NSTimeZone
31 | import platform.Foundation.autoupdatingCurrentLocale
32 | import platform.Foundation.localTimeZone
33 |
34 | actual fun getHttpClient(): HttpClient {
35 | val httpClient =
36 | HttpClient(Darwin) {
37 | engine {
38 | configureRequest {
39 | setTimeoutInterval(5 * 60.0)
40 | setAllowsCellularAccess(true)
41 | }
42 | }
43 | }
44 |
45 | return httpClient
46 | }
47 |
48 | private val cache: MutableMap = mutableMapOf()
49 |
50 | actual fun getFormattedDateTime(timestamp: String, format: String): String {
51 | val date = NSISO8601DateFormatter().dateFromString(timestamp) ?: return ""
52 |
53 | val dateFormatter = NSDateFormatter()
54 | dateFormatter.timeZone = NSTimeZone.localTimeZone
55 | dateFormatter.locale = NSLocale.autoupdatingCurrentLocale
56 | dateFormatter.dateFormat = format
57 | return dateFormatter.stringFromDate(date)
58 | }
59 |
60 | actual fun getPlatform(): Platform = Platform.iOS
61 |
62 | @OptIn(ExperimentalNativeApi::class) actual fun isDebug(): Boolean = NativePlatform.isDebugBinary
63 |
64 | @OptIn(ExperimentalComposeUiApi::class)
65 | @Composable
66 | actual fun getScreenHeight(): Int {
67 | return LocalWindowInfo.current.containerSize.height
68 | }
69 |
70 | @Composable
71 | actual fun UpdateSystemBars(
72 | statusBarColor: Color,
73 | navigationBarColor: Color,
74 | isDarkTheme: Boolean
75 | ) {}
76 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/core/utils/DatabaseDriverFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import app.cash.sqldelight.db.SqlDriver
19 | import app.cash.sqldelight.driver.native.NativeSqliteDriver
20 | import app.cash.sqldelight.driver.native.wrapConnection
21 | import co.touchlab.sqliter.DatabaseConfiguration
22 | import dev.ishubhamsingh.splashy.db.SplashyDatabase
23 |
24 | /** Created by Shubham Singh on 11/08/23. */
25 | actual class DatabaseDriverFactory {
26 | actual fun createDriver(): SqlDriver {
27 | return NativeSqliteDriver(
28 | DatabaseConfiguration(
29 | name = DB_NAME,
30 | version = SplashyDatabase.Schema.version.toInt(),
31 | create = { connection -> wrapConnection(connection) { SplashyDatabase.Schema.create(it) } },
32 | upgrade = { connection, oldVersion, newVersion ->
33 | wrapConnection(connection) {
34 | SplashyDatabase.Schema.migrate(it, oldVersion.toLong(), newVersion.toLong())
35 | }
36 | }
37 | )
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/dev/ishubhamsingh/splashy/core/utils/FileUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dev.ishubhamsingh.splashy.core.utils
17 |
18 | import com.eygraber.uri.Uri
19 | import dev.ishubhamsingh.splashy.features.details.WallpaperScreenType
20 | import dev.ishubhamsingh.splashy.resources.Res
21 | import dev.ishubhamsingh.splashy.resources.saved_failure_message
22 | import dev.ishubhamsingh.splashy.resources.saved_success_message
23 | import kotlin.coroutines.coroutineContext
24 | import kotlinx.cinterop.BetaInteropApi
25 | import kotlinx.cinterop.ExperimentalForeignApi
26 | import kotlinx.cinterop.allocArrayOf
27 | import kotlinx.cinterop.memScoped
28 | import kotlinx.coroutines.CoroutineScope
29 | import kotlinx.coroutines.Dispatchers
30 | import kotlinx.coroutines.IO
31 | import kotlinx.coroutines.launch
32 | import org.jetbrains.compose.resources.getString
33 | import platform.Foundation.NSData
34 | import platform.Foundation.create
35 | import platform.UIKit.UIImage
36 | import platform.UIKit.UIImageWriteToSavedPhotosAlbum
37 |
38 | /** Created by Shubham Singh on 19/08/23. */
39 | actual class FileUtils {
40 | @OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
41 | actual suspend fun saveByteArrayToFile(
42 | fileName: String,
43 | data: ByteArray,
44 | shouldOpenFile: Boolean,
45 | updateMessage: (String) -> Unit
46 | ) {
47 | var result = ""
48 | CoroutineScope(coroutineContext).launch(Dispatchers.IO) {
49 | runCatching {
50 | val nsData: NSData = memScoped {
51 | NSData.create(bytes = allocArrayOf(data), length = data.size.toULong())
52 | }
53 | val imageData = UIImage.imageWithData(data = nsData)
54 | if (imageData != null) {
55 | UIImageWriteToSavedPhotosAlbum(image = imageData, null, null, null)
56 | } else {
57 | throw NullPointerException()
58 | }
59 | }
60 | .onSuccess {
61 | result = getString(Res.string.saved_success_message)
62 | updateMessage.invoke(result)
63 | }
64 | .onFailure {
65 | result = getString(Res.string.saved_failure_message)
66 | updateMessage.invoke(result)
67 | it.printStackTrace()
68 | }
69 | }
70 | }
71 |
72 | actual suspend fun openFile(uri: Uri?, fileName: String) {
73 | // Do nothing
74 | }
75 |
76 | actual suspend fun applyWallpaper(
77 | data: ByteArray,
78 | wallpaperScreenType: WallpaperScreenType,
79 | updateMessage: (String) -> Unit
80 | ) {
81 | // Do nothing
82 | }
83 |
84 | actual suspend fun shouldAskStorageRuntimePermission(): Boolean {
85 | return true
86 | }
87 |
88 | actual suspend fun showMessage(message: String) {
89 | // Do nothing
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/gradle.bat:
--------------------------------------------------------------------------------
1 |
2 | @rem
3 | @rem Copyright 2015 the original author or authors.
4 | @rem
5 | @rem Licensed under the Apache License, Version 2.0 (the "License");
6 | @rem you may not use this file except in compliance with the License.
7 | @rem You may obtain a copy of the License at
8 | @rem
9 | @rem https://www.apache.org/licenses/LICENSE-2.0
10 | @rem
11 | @rem Unless required by applicable law or agreed to in writing, software
12 | @rem distributed under the License is distributed on an "AS IS" BASIS,
13 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | @rem See the License for the specific language governing permissions and
15 | @rem limitations under the License.
16 | @rem
17 |
18 | @if "%DEBUG%" == "" @echo off
19 | @rem ##########################################################################
20 | @rem
21 | @rem Gradle startup script for Windows
22 | @rem
23 | @rem ##########################################################################
24 |
25 | @rem Set local scope for the variables with windows NT shell
26 | if "%OS%"=="Windows_NT" setlocal
27 |
28 | set DIRNAME=%~dp0
29 | if "%DIRNAME%" == "" set DIRNAME=.
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if "%ERRORLEVEL%" == "0" goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 |
2 | #Gradle
3 | org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
4 |
5 | #Kotlin
6 | kotlin.code.style=official
7 | kotlin.js.compiler=ir
8 |
9 | #MPP
10 | kotlin.mpp.enableCInteropCommonization=true
11 | kotlin.mpp.androidSourceSetLayoutVersion=2
12 |
13 | #Compose
14 | org.jetbrains.compose.experimental.uikit.enabled=true
15 | org.jetbrains.compose.experimental.jscanvas.enabled=true
16 |
17 | #Android
18 | android.useAndroidX=true
19 | android.nonTransitiveRClass=true
20 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 |
3 | kotlin = "2.1.21"
4 | agp = "8.10.1"
5 | compose = "1.7.1"
6 | coil = "3.0.0-alpha08"
7 | androidx-appcompat = "1.7.1"
8 | androidx-activityCompose = "1.9.3"
9 | compose-uitooling = "1.7.8"
10 | material = "1.12.0"
11 | napier = "2.7.1"
12 | buildConfig = "5.6.5"
13 | kotlinx-coroutines = "1.10.2"
14 | insetsx = "0.1.0-alpha10"
15 | ktor = "2.3.13"
16 | composeIcons = "1.1.1"
17 | kotlinx-serialization = "1.8.1"
18 | multiplatformSettings = "1.3.0"
19 | koin = "4.0.4"
20 | koin-compose = "4.0.4"
21 | sqlDelight = "2.1.0"
22 | spotless = "7.0.4"
23 | ktfmt = "0.44"
24 | statelyCommon = "2.1.0"
25 | voyager = "1.0.1"
26 | moko-permissions = "0.18.1"
27 | kotlinx-datetime = "0.6.2"
28 | uri-kmp = "0.0.19"
29 |
30 | [libraries]
31 |
32 | androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
33 | androidx-activityCompose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
34 | compose-uitooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose-uitooling" }
35 | coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil"}
36 | coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil"}
37 | coil-ktor = { module = "io.coil-kt.coil3:coil-network-ktor", version.ref = "coil"}
38 | material = { module = "com.google.android.material:material", version.ref = "material" }
39 | napier = { module = "io.github.aakira:napier", version.ref = "napier" }
40 | kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
41 | kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
42 | insetsx = { module = "com.moriatsushi.insetsx:insetsx", version.ref = "insetsx" }
43 | ktor-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
44 | ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
45 | ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
46 | ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
47 | ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
48 | ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
49 | composeIcons-featherIcons = { module = "br.com.devsrsouza.compose.icons:feather", version.ref = "composeIcons" }
50 | composeIcons-evaIcons = { module = "br.com.devsrsouza.compose.icons:eva-icons", version.ref = "composeIcons" }
51 | composeIcons-octicons = { module = "br.com.devsrsouza.compose.icons:octicons", version.ref = "composeIcons" }
52 | kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
53 | multiplatformSettings = { module = "com.russhwolf:multiplatform-settings-no-arg", version.ref = "multiplatformSettings" }
54 | koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
55 | koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin-compose" }
56 | koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
57 | koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
58 | sqlDelight-driver-sqlite = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqlDelight" }
59 | sqlDelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqlDelight" }
60 | sqlDelight-driver-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqlDelight" }
61 | sqlDelight-driver-sqljs = { module = "app.cash.sqldelight:sqljs-driver", version.ref = "sqlDelight" }
62 | sqlDelight-coroutines-extensions = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqlDelight" }
63 | sqlDelight-sqlite-dialect = { module = "app.cash.sqldelight:sqlite-3-24-dialect", version.ref = "sqlDelight" }
64 | stately-common = { module = "co.touchlab:stately-common", version.ref = "statelyCommon" }
65 | voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }
66 | voyager-tabNavigator = { module = "cafe.adriel.voyager:voyager-tab-navigator", version.ref = "voyager" }
67 | voyager-transitions = { module = "cafe.adriel.voyager:voyager-transitions", version.ref = "voyager" }
68 | voyager-koin = { module = "cafe.adriel.voyager:voyager-koin", version.ref = "voyager" }
69 | moko-permissions = { module = "dev.icerock.moko:permissions-compose", version.ref = "moko-permissions"}
70 | kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime"}
71 | uri-kmp = { module = "com.eygraber:uri-kmp", version.ref = "uri-kmp" }
72 |
73 |
74 | [plugins]
75 |
76 | multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
77 | cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
78 | compose = { id = "org.jetbrains.compose", version.ref = "compose" }
79 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
80 | android-application = { id = "com.android.application", version.ref = "agp" }
81 | buildConfig = { id = "com.github.gmazzo.buildconfig", version.ref = "buildConfig" }
82 | kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
83 | sqlDelight = { id = "app.cash.sqldelight", version.ref = "sqlDelight" }
84 | spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/iosApp/Configuration/Config.xcconfig:
--------------------------------------------------------------------------------
1 | TEAM_ID=A5CX8H4MPQ
2 | BUNDLE_ID=dev.ishubhamsingh.splashy.iosApp
3 | APP_NAME=Splashy
4 |
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/xcshareddata/xcschemes/iosApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
42 |
44 |
50 |
51 |
52 |
53 |
59 |
61 |
67 |
68 |
69 |
70 |
72 |
73 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@2x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon@3x.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon~ipad.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "filename": "AppIcon@2x.png",
5 | "idiom": "iphone",
6 | "scale": "2x",
7 | "size": "60x60"
8 | },
9 | {
10 | "filename": "AppIcon@3x.png",
11 | "idiom": "iphone",
12 | "scale": "3x",
13 | "size": "60x60"
14 | },
15 | {
16 | "filename": "AppIcon~ipad.png",
17 | "idiom": "ipad",
18 | "scale": "1x",
19 | "size": "76x76"
20 | },
21 | {
22 | "filename": "AppIcon@2x~ipad.png",
23 | "idiom": "ipad",
24 | "scale": "2x",
25 | "size": "76x76"
26 | },
27 | {
28 | "filename": "AppIcon-83.5@2x~ipad.png",
29 | "idiom": "ipad",
30 | "scale": "2x",
31 | "size": "83.5x83.5"
32 | },
33 | {
34 | "filename": "AppIcon-40@2x.png",
35 | "idiom": "iphone",
36 | "scale": "2x",
37 | "size": "40x40"
38 | },
39 | {
40 | "filename": "AppIcon-40@3x.png",
41 | "idiom": "iphone",
42 | "scale": "3x",
43 | "size": "40x40"
44 | },
45 | {
46 | "filename": "AppIcon-40~ipad.png",
47 | "idiom": "ipad",
48 | "scale": "1x",
49 | "size": "40x40"
50 | },
51 | {
52 | "filename": "AppIcon-40@2x~ipad.png",
53 | "idiom": "ipad",
54 | "scale": "2x",
55 | "size": "40x40"
56 | },
57 | {
58 | "filename": "AppIcon-20@2x.png",
59 | "idiom": "iphone",
60 | "scale": "2x",
61 | "size": "20x20"
62 | },
63 | {
64 | "filename": "AppIcon-20@3x.png",
65 | "idiom": "iphone",
66 | "scale": "3x",
67 | "size": "20x20"
68 | },
69 | {
70 | "filename": "AppIcon-20~ipad.png",
71 | "idiom": "ipad",
72 | "scale": "1x",
73 | "size": "20x20"
74 | },
75 | {
76 | "filename": "AppIcon-20@2x~ipad.png",
77 | "idiom": "ipad",
78 | "scale": "2x",
79 | "size": "20x20"
80 | },
81 | {
82 | "filename": "AppIcon-29.png",
83 | "idiom": "iphone",
84 | "scale": "1x",
85 | "size": "29x29"
86 | },
87 | {
88 | "filename": "AppIcon-29@2x.png",
89 | "idiom": "iphone",
90 | "scale": "2x",
91 | "size": "29x29"
92 | },
93 | {
94 | "filename": "AppIcon-29@3x.png",
95 | "idiom": "iphone",
96 | "scale": "3x",
97 | "size": "29x29"
98 | },
99 | {
100 | "filename": "AppIcon-29~ipad.png",
101 | "idiom": "ipad",
102 | "scale": "1x",
103 | "size": "29x29"
104 | },
105 | {
106 | "filename": "AppIcon-29@2x~ipad.png",
107 | "idiom": "ipad",
108 | "scale": "2x",
109 | "size": "29x29"
110 | },
111 | {
112 | "filename": "AppIcon-60@2x~car.png",
113 | "idiom": "car",
114 | "scale": "2x",
115 | "size": "60x60"
116 | },
117 | {
118 | "filename": "AppIcon-60@3x~car.png",
119 | "idiom": "car",
120 | "scale": "3x",
121 | "size": "60x60"
122 | },
123 | {
124 | "filename": "AppIcon~ios-marketing.png",
125 | "idiom": "ios-marketing",
126 | "scale": "1x",
127 | "size": "1024x1024"
128 | }
129 | ],
130 | "info": {
131 | "author": "xcode",
132 | "version": 1
133 | }
134 | }
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/iosApp/iosApp/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | CADisableMinimumFrameDurationOnPhone
24 |
25 | UIApplicationSceneManifest
26 |
27 | UIApplicationSupportsMultipleScenes
28 |
29 |
30 | UILaunchScreen
31 |
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | NSPhotoLibraryAddUsageDescription
50 | Our application needs permission to write photos to support download feature
51 |
52 |
53 |
--------------------------------------------------------------------------------
/iosApp/iosApp/iosApp.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SwiftUI
3 | import ComposeApp
4 | import Foundation
5 |
6 | @main
7 | struct iosApp: App {
8 |
9 | init() {
10 | LoggingKt.initialiseLogging()
11 | DIHelperKt.doInitKoin()
12 | }
13 | var body: some Scene {
14 | WindowGroup {
15 | ContentView()
16 | }
17 | }
18 | }
19 |
20 | class ContainerViewController: UIViewController {
21 | private let onTouchDown: (CGPoint) -> Void
22 |
23 | init(child: UIViewController, onTouchDown: @escaping (CGPoint) -> Void) {
24 | self.onTouchDown = onTouchDown
25 | super.init(nibName: nil, bundle: nil)
26 | addChild(child)
27 | child.view.frame = view.frame
28 | view.addSubview(child.view)
29 | child.didMove(toParent: self)
30 | }
31 |
32 | required init?(coder: NSCoder) {
33 | fatalError("init(coder:) has not been implemented")
34 | }
35 |
36 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
37 | super.touchesBegan(touches, with: event)
38 | if let startPoint = touches.first?.location(in: nil) {
39 | onTouchDown(startPoint)
40 | }
41 | }
42 | }
43 |
44 | struct SwipeGestureViewController: UIViewControllerRepresentable {
45 | var onSwipe: () -> Void
46 |
47 | func makeUIViewController(context: Context) -> UIViewController {
48 | let viewController = App_iosKt.MainViewController()
49 | let containerController = ContainerViewController(child: viewController) {
50 | context.coordinator.startPoint = $0
51 | }
52 |
53 | let swipeGestureRecognizer = UISwipeGestureRecognizer(
54 | target:
55 | context.coordinator, action: #selector(Coordinator.handleSwipe)
56 | )
57 | swipeGestureRecognizer.direction = .right
58 | swipeGestureRecognizer.numberOfTouchesRequired = 1
59 | containerController.view.addGestureRecognizer(swipeGestureRecognizer)
60 | return containerController
61 | }
62 |
63 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
64 |
65 | func makeCoordinator() -> Coordinator {
66 | Coordinator(onSwipe: onSwipe)
67 | }
68 |
69 | class Coordinator: NSObject, UIGestureRecognizerDelegate {
70 | var onSwipe: () -> Void
71 | var startPoint: CGPoint?
72 |
73 | init(onSwipe: @escaping () -> Void) {
74 | self.onSwipe = onSwipe
75 | }
76 |
77 | @objc func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
78 | if gesture.state == .ended, let startPoint = startPoint, startPoint.x < 50 {
79 | onSwipe()
80 | }
81 | }
82 |
83 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
84 | true
85 | }
86 | }
87 | }
88 |
89 | struct ContentView: View {
90 | var body: some View {
91 | VStack {
92 | SwipeGestureViewController {
93 | onBackGesture()
94 | }
95 | }.ignoresSafeArea(.all, edges: .vertical)
96 | }
97 | }
98 |
99 | public func onBackGesture() {
100 | App_iosKt.OnBackGesture()
101 | }
102 |
--------------------------------------------------------------------------------
/keystore/splashy.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishubhamsingh/Splashy/12daf0ea43928449473b68eee1bbed054edeaeb0/keystore/splashy.jks
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ],
6 | "automergeType": "branch",
7 | "packageRules": [
8 | {
9 | "description": "Automerge non-major updates",
10 | "matchUpdateTypes": ["minor", "patch"],
11 | "automerge": true
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | rootProject.name = "Splashy"
17 |
18 | include(":composeApp")
19 |
20 | pluginManagement {
21 | repositories {
22 | google()
23 | gradlePluginPortal()
24 | mavenCentral()
25 | maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
26 | }
27 | }
28 |
29 | dependencyResolutionManagement {
30 | @Suppress("UnstableApiUsage")
31 | repositories {
32 | google()
33 | mavenCentral()
34 | maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/spotless/copyright.txt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright $YEAR Shubham Singh
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
--------------------------------------------------------------------------------