diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7687510..d4c5c90 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,45 +14,31 @@ jobs:
shell: bash
steps:
- - uses: actions/checkout@v2
- - name: set up JDK 11
- uses: actions/setup-java@v2
- with:
- java-version: '11'
- distribution: 'adopt'
-
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
-
- - name: Get Extra files
- uses: prewk/s3-cp-action@v1
- env:
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- AWS_REGION: 'eu-west-1'
- SOURCE: 's3://splitbus/gmaps.zip'
- DEST: './app/src/main/java/com/am/stbus/presentation/screens'
-
- - name: Unzip extra files
- run: |
- echo "Poceo unzip"
- cd app/src/main/java/com/am/stbus/presentation/screens
- ls
- unzip gmaps.zip
- echo "Gotov unzip"
-
- - name: Add Google services JSON
- run: |
- cd app
- ls
- echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > google-services.json
- echo "Gotov Google services JSON"
-
- - name: Update gradleProperties
- id: createServiceAccount
- run: |
- echo "first message"
- echo '${{ secrets.GRADLE_PROPERTIES }}' > gradle.properties
-
- - name: Build with Gradle
- run: ./gradlew buildRelease
+ - uses: actions/checkout@v3
+ - name: Setup JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Set up Android SDK
+ uses: android-actions/setup-android@v2
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+
+ - name: Add Google services JSON
+ run: |
+ cd app
+ ls
+ echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > google-services.json
+ echo "Gotov Google services JSON"
+
+ - name: Update secrets
+ id: updateSecrets
+ run: |
+ echo "Updating Secrets.kt"
+ echo '${{ secrets.SECRETS }}' > app/src/main/java/com/am/stbus/common/Secrets.kt
+
+ - name: Build with Gradle
+ run: ./gradlew buildRelease
diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml
index 41e5727..13294a8 100644
--- a/.github/workflows/upload.yml
+++ b/.github/workflows/upload.yml
@@ -14,70 +14,56 @@ jobs:
shell: bash
steps:
- - uses: actions/checkout@v2
- - name: set up JDK 11
- uses: actions/setup-java@v2
- with:
- java-version: '11'
- distribution: 'adopt'
+ - uses: actions/checkout@v3
+ - name: Setup JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
+ - name: Set up Android SDK
+ uses: android-actions/setup-android@v2
- - name: Get Extra files
- uses: prewk/s3-cp-action@v1
- env:
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- AWS_REGION: 'eu-west-1'
- SOURCE: 's3://splitbus/gmaps.zip'
- DEST: './app/src/main/java/com/am/stbus/presentation/screens'
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
- - name: Unzip extra files
- run: |
- echo "Poceo unzip"
- cd app/src/main/java/com/am/stbus/presentation/screens
- ls
- unzip gmaps.zip
- echo "Gotov unzip"
+ - name: Add Google services JSON
+ run: |
+ cd app
+ ls
+ echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > google-services.json
+ echo "Gotov Google services JSON"
- - name: Add Google services JSON
- run: |
- cd app
- ls
- echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > google-services.json
- echo "Gotov Google services JSON"
+ - name: Update secrets
+ id: updateSecrets
+ run: |
+ echo "Updating Secrets.kt"
+ echo '${{ secrets.SECRETS }}' > app/src/main/java/com/am/stbus/common/Secrets.kt
- - name: Update gradleProperties
- id: gradleProperties
- run: |
- echo "first message"
- echo '${{ secrets.GRADLE_PROPERTIES }}' > gradle.properties
+ - name: Build Release AAB
+ id: buildRelease
+ run: ./gradlew bundleRelease
- - name: Build Release AAB
- id: buildRelease
- run: ./gradlew bundleRelease
+ - name: Sign AAB
+ id: sign
+ uses: r0adkll/sign-android-release@v1
+ with:
+ releaseDirectory: app/build/outputs/bundle/release
+ signingKeyBase64: ${{ secrets.KEY_SIGNING }}
+ alias: ${{ secrets.KEY_ALIAS }}
+ keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
+ keyPassword: ${{ secrets.KEY_PASSWORD }}
- - name: Sign AAB
- id: sign
- uses: r0adkll/sign-android-release@v1
- with:
- releaseDirectory: app/build/outputs/bundle/release
- signingKeyBase64: ${{ secrets.KEY_SIGNING }}
- alias: ${{ secrets.KEY_ALIAS }}
- keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
- keyPassword: ${{ secrets.KEY_PASSWORD }}
+ - name: Create service_account.json
+ id: createServiceAccount
+ run: echo '${{ secrets.SERVICE_ACCOUNT_JSON }}' > service_account.json
- - name: Create service_account.json
- id: createServiceAccount
- run: echo '${{ secrets.SERVICE_ACCOUNT_JSON }}' > service_account.json
-
- - name: Deploy to Play Store (BETA)
- id: deploy
- uses: r0adkll/upload-google-play@v1
- with:
- serviceAccountJson: service_account.json
- packageName: com.am.stbus
- releaseFiles: app/build/outputs/bundle/release/app-release.aab
- track: internal
- status: completed
\ No newline at end of file
+ - name: Deploy to Play Store (BETA)
+ id: deploy
+ uses: r0adkll/upload-google-play@v1
+ with:
+ serviceAccountJson: service_account.json
+ packageName: com.am.stbus
+ releaseFiles: app/build/outputs/bundle/release/app-release.aab
+ track: internal
+ status: completed
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index fe433ff..b3ab340 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,82 +1,54 @@
-# Built application files
-*.apk
-*.ap_
-
-# Files for the ART/Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-bin/
-gen/
-out/
-
# Gradle files
.gradle/
build/
+**/build/
# Local configuration file (sdk path, etc)
local.properties
+Secrets.kt
-# Proguard folder generated by Eclipse
-proguard/
-
-# Log Files
+# Log files
*.log
-# Android Studio Navigation editor temp files
-.navigation/
-
-# Android Studio captures folder
-captures/
-
-# Intellij
+# Android Studio
+.idea/
*.iml
-.idea/workspace.xml
-.idea/tasks.xml
-.idea/gradle.xml
-.idea/assetWizardSettings.xml
-.idea/dictionaries
-.idea/libraries
-# Android Studio 3 in .gitignore file.
-.idea/caches
-.idea/modules.xml
-# Comment next line if keeping position of elements in Navigation Editor is relevant for you
-.idea/navEditor.xml
-
-# Keystore files
-*.jks
-
-# External native build folder generated in Android Studio 2.2 and later
-.externalNativeBuild
+*.ipr
+*.iws
+out/
-# Google Services (e.g. APIs or Firebase)
-google-services.json
+# Kotlin and Java compiled files
+*.class
+*.jar
+*.war
+*.ear
+*.dex
-# Freeline
-freeline.py
-freeline/
-freeline_project_description.json
+# Generated files
+gen/
+bin/
+captures/
+output.json
-# Fastlane
-fastlane/
-Gemfile
-Gemfile.lock
+# IntelliJ
+*.hprof
-# Android
-release/
-release/res/values/
+# Gradle caches and wrapper
+!gradle/wrapper/gradle-wrapper.jar
-# Podatci za Google Maps
-gmaps/
+# Signing keys (don’t commit these!)
+*.keystore
+*.jks
-# Gmaps config
-gradle.properties
+# NDK / CMake / Native build
+.externalNativeBuild/
+.cxx/
-# Changelog generator
-changelog.sh
+# OS-specific
+.DS_Store
+Thumbs.db
-/.idea/deploymentTargetDropDown.xml
-/.idea/kotlinc.xml
+# Others
+*.apk
+*.ap_
+*.aab
diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000..4a53bee
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 88ea3aa..3b25318 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,5 +1,39 @@
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b589d56..b86273d 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index b946f4b..bd6abc9 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index 2d27d91..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-android-extensions'
-apply plugin: 'kotlin-kapt'
-apply plugin: 'androidx.navigation.safeargs.kotlin'
-apply plugin: 'com.google.gms.google-services'
-apply plugin: 'com.google.firebase.crashlytics'
-apply plugin: 'com.google.android.gms.oss-licenses-plugin'
-
-android {
- compileSdkVersion 33
-
- defaultConfig {
- applicationId "com.am.stbus"
- minSdkVersion 19
- targetSdkVersion 33
- versionCode 80
- versionName "3.2.3"
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- android.defaultConfig.vectorDrawables.useSupportLibrary = true
- multiDexEnabled true
- }
-
- buildTypes {
- debug {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- buildConfigField "java.util.Date", "BUILD_TIME", "new java.util.Date(" + System.currentTimeMillis() + "L)"
- resValue 'string', "api_key", gmaps_debug_key
- applicationIdSuffix ".dev"
- versionNameSuffix "." + "-dev"
- }
-
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- buildConfigField "java.util.Date", "BUILD_TIME", "new java.util.Date(" + System.currentTimeMillis() + "L)"
- resValue 'string', "api_key", gmaps_release_key
- }
-
- }
-
-
- compileOptions {
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
- }
-
- kotlinOptions {
- jvmTarget = "1.8"
- }
- lint {
- abortOnError false
- checkReleaseBuilds false
- }
-
- //namespace 'com.am.stbus'
-
-}
-
-ext {
- // AndroidX
- appcompat_version = "1.4.1"
- core_ktx_version = "1.7.0"
- recyclerview_version = "1.2.1"
- browser_version = "1.4.0"
- swipe_refresh_version = "1.1.0"
- constraint_layout_version = "2.1.4"
- vector_drawable_version = "1.0.0"
- preference_ktx_version = "1.2.0"
-
- // Navigation
- nav_version_ktx_version = "2.4.2"
-
- // ViewModel and LiveData
- lifecycle_version = "2.2.0"
-
- // Room
- room_version = "2.4.2"
-
- // Gmaps
- play_services_maps_version = "18.0.2"
- play_services_location_version = "19.0.1"
-
- // Firebase Analytics
- firebase_analytics_version = "21.0.0"
- firebase_crashlytics_version = "18.2.11"
-
- // Material
- material_components_version = "1.7.0-alpha02"
-
- // Koin
- koin_version = "3.2.0"
-
- // RxF
- rx_android_version = "2.1.1"
- rx_kotlin_version = "2.3.0"
-
- // Jsoup
- jsoup_version = "1.15.1"
-
- // ThreeTen
- three_ten_abp_version = "1.4.0"
-
- // Timber
- timber_version = "5.0.1"
-
- // Glide
- glide_version = "4.13.0"
-
- // Photo view
- photoview_version = "2.3.0"
-
- // licenses
- licenses_version = "17.0.0"
-}
-
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21"
- // implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
-
- // Testing
- implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
- testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'androidx.test:runner:1.5.0-alpha04'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0-alpha07'
-
- // AndroidX
- implementation "androidx.appcompat:appcompat:$appcompat_version"
- implementation "androidx.core:core-ktx:$core_ktx_version"
- implementation "androidx.recyclerview:recyclerview:$recyclerview_version"
- implementation "androidx.browser:browser:$browser_version"
- implementation "androidx.swiperefreshlayout:swiperefreshlayout:$swipe_refresh_version"
- implementation "androidx.constraintlayout:constraintlayout:$constraint_layout_version"
- implementation "androidx.vectordrawable:vectordrawable:$vector_drawable_version"
- implementation "androidx.preference:preference-ktx:$preference_ktx_version"
-
- // Navigation
- implementation "androidx.navigation:navigation-fragment-ktx:$nav_version_ktx_version"
- implementation "androidx.navigation:navigation-ui-ktx:$nav_version_ktx_version"
-
- // ViewModel and LiveData
- implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
- kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
-
- // Room
- implementation "androidx.room:room-runtime:$room_version"
- kapt "androidx.room:room-compiler:$room_version"
- implementation "androidx.room:room-ktx:$room_version"
- implementation "androidx.room:room-rxjava2:$room_version"
-
- // Gmaps
- implementation "com.google.android.gms:play-services-maps:$play_services_maps_version"
- implementation "com.google.android.gms:play-services-location:$play_services_location_version"
-
- // Firebase Analytics
- implementation "com.google.firebase:firebase-analytics:$firebase_analytics_version"
- implementation "com.google.firebase:firebase-crashlytics:$firebase_crashlytics_version"
-
- // Material Components
- implementation "com.google.android.material:material:$material_components_version"
-
- // Koin
- implementation "io.insert-koin:koin-core:$koin_version"
- implementation "io.insert-koin:koin-android:$koin_version"
- implementation "io.insert-koin:koin-androidx-navigation:$koin_version"
-
- // Rx
- implementation "io.reactivex.rxjava2:rxandroid:$rx_android_version"
- implementation "io.reactivex.rxjava2:rxkotlin:$rx_kotlin_version"
-
- // Jsoup
- implementation "org.jsoup:jsoup:$jsoup_version"
-
- // ThreeTen
- implementation "com.jakewharton.threetenabp:threetenabp:$three_ten_abp_version"
-
- // Timber for Logging
- implementation "com.jakewharton.timber:timber:$timber_version"
-
- // Glide
- implementation "com.github.bumptech.glide:glide:$glide_version"
- kapt "com.github.bumptech.glide:compiler:$glide_version"
-
- // PhotoView
- implementation "com.github.chrisbanes:PhotoView:$photoview_version"
-
- // Libraries
- implementation "com.google.android.gms:play-services-oss-licenses:$licenses_version"
-}
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..a3ab5ca
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,107 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.kotlin.compose)
+ alias(libs.plugins.jetbrains.kotlin.serialization)
+ alias(libs.plugins.ksp)
+}
+
+android {
+ namespace = "com.am.stbus"
+ compileSdk = 36
+
+ defaultConfig {
+ applicationId = "com.am.stbus"
+ minSdk = 23
+ targetSdk = 36
+ versionCode = 81
+ versionName = "4.0.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ debug {
+ isMinifyEnabled = false
+ applicationIdSuffix = ".dev"
+ versionNameSuffix = "." + "-dev"
+ }
+ release {
+ isMinifyEnabled = true
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+ buildFeatures {
+ compose = true
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+
+ //implementation(libs.androidx.navigation3)
+ implementation(libs.androidx.lifecycle.viewmodel.navigation3)
+ implementation(libs.kotlinx.serialization.core)
+
+ implementation(libs.kotlinx.coroutines.android)
+
+ implementation(libs.room.runtime)
+ ksp(libs.room.compiler)
+ implementation(libs.room.ktx)
+
+ implementation(platform(libs.koin.bom))
+ implementation(libs.koin.android)
+ implementation(libs.koin.compose)
+ implementation(libs.koin.core.coroutines)
+ implementation(libs.koin.androidx.workmanager)
+
+ implementation(libs.jakewharton.timber)
+ implementation(libs.jakewharton.threetenabp)
+ implementation(libs.squareup.retrofit)
+ implementation(libs.squareup.retrofit.serialization)
+
+
+ /*
+ implementation(libs.androidx.material3.windowsizeclass)
+ implementation(libs.androidx.adaptive.layout)
+ implementation(libs.androidx.material3.navigation3)
+ */
+
+ implementation(libs.kotlinx.serialization.core)
+ implementation(libs.kotlinx.serialization.json)
+ implementation(libs.androidx.navigation3.runtime)
+ implementation(libs.androidx.navigation3.ui)
+ implementation(libs.androidx.lifecycle.viewmodel.navigation3)
+ implementation(libs.androidx.material.icons.extended)
+ implementation(libs.androidx.navigation.fragment.ktx)
+ implementation(libs.androidx.navigation.ui.ktx)
+ implementation(libs.jsoup)
+ implementation(libs.androidx.navigation3.runtime)
+
+ testImplementation(libs.junit)
+ testImplementation(libs.kotlinx.coroutines.test)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+ testImplementation(kotlin("test"))
+}
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..abf62a2
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,91 @@
+{
+ "project_info": {
+ "project_number": "123",
+ "firebase_url": "https://android-app.firebaseio.com",
+ "project_id": "android-app",
+ "storage_bucket": "test.com,"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "123",
+ "android_client_info": {
+ "package_name": "com.am.stbus"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "123",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.am.stbus",
+ "certificate_hash": "456"
+ }
+ },
+ {
+ "client_id": "123.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "456"
+ },
+ {
+ "current_key": "789"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "123.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "123",
+ "android_client_info": {
+ "package_name": "com.am.stbus.dev"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "123.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.am.stbus.dev",
+ "certificate_hash": "345"
+ }
+ },
+ {
+ "client_id": "123.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "456"
+ },
+ {
+ "current_key": "789"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "12345.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3108668..3ecf819 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -25,8 +25,7 @@
-->
+ xmlns:tools="http://schemas.android.com/tools">
@@ -38,7 +37,6 @@
-
+
+ android:value="@integer/google_play_services_version" /> <!– Fixes crash for Android 9+ users –>
+ -->
diff --git a/app/src/main/java/com/am/stbus/SplitBusApplication.kt b/app/src/main/java/com/am/stbus/SplitBusApplication.kt
index e8e1b8a..ac5d1a3 100644
--- a/app/src/main/java/com/am/stbus/SplitBusApplication.kt
+++ b/app/src/main/java/com/am/stbus/SplitBusApplication.kt
@@ -25,7 +25,11 @@
package com.am.stbus
import android.app.Application
-import com.am.stbus.common.di.*
+import com.am.stbus.common.di.appModule
+import com.am.stbus.common.di.networkModule
+import com.am.stbus.common.di.repositoryModule
+import com.am.stbus.common.di.useCaseModule
+import com.am.stbus.common.di.viewModelModule
import com.jakewharton.threetenabp.AndroidThreeTen
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
@@ -33,13 +37,21 @@ import timber.log.Timber
class SplitBusApplication : Application() {
+/* private var listOfModules = listOf(
+ applicationModule,
+ localModules,
+ networkModules,
+ repositoriesModule,
+ useCaseModule,
+ viewModelModule
+ )*/
+
private var listOfModules = listOf(
- applicationModule,
- localModules,
- networkModules,
- repositoriesModule,
- useCaseModule,
- viewModelModule
+ appModule,
+ networkModule,
+ repositoryModule,
+ useCaseModule,
+ viewModelModule
)
override fun onCreate() {
@@ -57,9 +69,11 @@ class SplitBusApplication : Application() {
}
private fun setupTimber() {
- if (BuildConfig.DEBUG) {
- Timber.plant(Timber.DebugTree())
- }
+ Timber.plant(Timber.DebugTree())
+
+ /* if (BuildConfig.DEBUG) {
+ Timber.plant(Timber.DebugTree())
+ }*/
}
private fun setupThreeTen() {
diff --git a/app/src/main/java/com/am/stbus/common/Constants.kt b/app/src/main/java/com/am/stbus/common/Constants.kt
index 53d2adc..48a35d3 100644
--- a/app/src/main/java/com/am/stbus/common/Constants.kt
+++ b/app/src/main/java/com/am/stbus/common/Constants.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,10 +26,14 @@ package com.am.stbus.common
object Constants {
- const val DB_VERSION = 5
+ const val DB_VERSION = 1
const val PROMET_URL = "http://www.promet-split.hr"
const val PROMET_NOVOSTI_URL = "http://www.promet-split.hr/obavijesti"
+ const val PROMET_API_URL = "https://api.promet-split.hr/Fleet/api/v1/"
+ const val PROMET_ALL_LINES_URL = "$PROMET_URL/vozni-red/sve-linije/"
+ const val PROMET_ALL_LINE_ID_URL = "$PROMET_URL/vozni-red/sve-linije/linijaid/"
+
// Timetable Base URLs
const val AREA_CITY_URL = "$PROMET_URL/vozni-red/split/"
@@ -78,17 +82,20 @@ object InformationConstants {
const val ID_PROMET_WEB = 12
// Informacije
- const val KARTA_GRAD_URL = "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/grad.jpg"
- const val KARTA_PRIGRAD_URL = "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/prigrad.jpg"
- const val TARIFNE_URL = "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/tarifne.jpg"
+ const val KARTA_GRAD_URL =
+ "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/grad.jpg"
+ const val KARTA_PRIGRAD_URL =
+ "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/prigrad.jpg"
+ const val TARIFNE_URL =
+ "https://splitbuspublic.s3.eu-central-1.amazonaws.com/public/tarifne.jpg"
const val NEXT_BIKE_URL = "https://www.nextbike.hr/hr/split/lokacije/"
const val PARKING_URL = "http://www.splitparking.hr/parkiralista"
const val GARAZE_URL = "http://www.splitparking.hr/garaze"
- const val NEXT_BIKE_IFRAME = ""
-
-}
+ const val NEXT_BIKE_IFRAME =
+ ""
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/models/GmapsBusStop.kt b/app/src/main/java/com/am/stbus/common/Secrets.kt
similarity index 87%
rename from app/src/main/java/com/am/stbus/domain/models/GmapsBusStop.kt
rename to app/src/main/java/com/am/stbus/common/Secrets.kt
index f1aad42..ac02ad4 100644
--- a/app/src/main/java/com/am/stbus/domain/models/GmapsBusStop.kt
+++ b/app/src/main/java/com/am/stbus/common/Secrets.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.models
+package com.am.stbus.common
-data class GmapsBusStop(var title: String, var busLinesArray: ArrayList)
\ No newline at end of file
+val PROMET_KEY = "placeholder"
+val GMAPS_DEBUG_KEY = "test"
+val GMAPS_RELEASE_KEY = "test2"
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/TimetablesData.kt b/app/src/main/java/com/am/stbus/common/TimetablesData.kt
deleted file mode 100644
index e83e11c..0000000
--- a/app/src/main/java/com/am/stbus/common/TimetablesData.kt
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.common
-
-import com.am.stbus.R
-import com.am.stbus.domain.models.Timetable
-
-class TimetablesData {
-
- fun getTimetableTitle(lineId: Int): Int =
- when (lineId) {
- // Gradski
- 1 -> R.string.bus32
- 2 -> R.string.bus31
- 3 -> R.string.bus6
- 4 -> R.string.bus71
- 5 -> R.string.bus72
- 6 -> R.string.bus81
- 7 -> R.string.bus82
- 8 -> R.string.bus9
- 9 -> R.string.bus111
- 10 -> R.string.bus112
- 11 -> R.string.bus121
- 12 -> R.string.bus122
- 13 -> R.string.bus141
- 14 -> R.string.bus142
- 15 -> R.string.bus15
- 16 -> R.string.bus171
- 17 -> R.string.bus172
- 18 -> R.string.bus18
- 19 -> R.string.bus20
- 20 -> R.string.bus21
- 21 -> R.string.bus241
- 22 -> R.string.bus242
- 23 -> R.string.bus251
- 24 -> R.string.bus252
- 25 -> R.string.bus261
- 26 -> R.string.bus262
- 27 -> R.string.bus271
- 28 -> R.string.bus272
- 29 -> R.string.bus39
- 30 -> R.string.bus40
-
-
- // Urbano
- 101 -> R.string.bus1
- 102 -> R.string.bus021
- 103 -> R.string.bus022
- 104 -> R.string.bus023
- 105 -> R.string.bus5
- 106 -> R.string.bus51
- 107 -> R.string.bus10
- 108 -> R.string.bus16
- 109 -> R.string.bus22
- 110 -> R.string.bus23
- 111 -> R.string.bus281
- 112 -> R.string.bus282
- 113 -> R.string.bus291
- 114 -> R.string.bus292
- 115 -> R.string.bus301
- 116 -> R.string.bus302
- 117 -> R.string.bus311
- 118 -> R.string.bus312
- 119 -> R.string.bus321
- 120 -> R.string.bus322
- 121 -> R.string.bus331
- 122 -> R.string.bus332
- 123 -> R.string.bus341
- 124 -> R.string.bus342
- 125 -> R.string.bus351
- 126 -> R.string.bus352
- 127 -> R.string.bus361
- 128 -> R.string.bus362
- 129 -> R.string.bus371
- 130 -> R.string.bus372
- 131 -> R.string.bus381
- 132 -> R.string.bus382
- 133 -> R.string.bus601
- 134 -> R.string.bus602
- 135 -> R.string.zeljkstari
- 136 -> R.string.kstarizelj
- 137 -> R.string.trogir_kstari
- 138 -> R.string.kstari_trogir
- 139 -> R.string.trostdirekt2
-
- // Prigradsko
- 201 -> R.string.bus671
- 202 -> R.string.bus672
- 203 -> R.string.bus681
- 204 -> R.string.bus682
- 205 -> R.string.bus691
- 206 -> R.string.bus692
- 207 -> R.string.bus711
- 208 -> R.string.bus712
- 209 -> R.string.bus731
- 210 -> R.string.bus732
- 211 -> R.string.bus761
- 212 -> R.string.bus762
- 213 -> R.string.bus771
- 214 -> R.string.bus772
- 215 -> R.string.bus801
- 216 -> R.string.bus802
- 217 -> R.string.bus811
- 218 -> R.string.bus812
- 219 -> R.string.bus861
- 220 -> R.string.bus862
- // 84
- // 85
- // 86
- 221 -> R.string.bus900
- 222 -> R.string.bus911
- 223 -> R.string.bus912
- 224 -> R.string.bus931
- 225 -> R.string.bus932
- 226 -> R.string.kstarirudine
- 227 -> R.string.rudinekstari
-
-
- // Trogir i Solta
- 301 -> R.string.bus411
- 302 -> R.string.bus412
- 303 -> R.string.bus421
- 304 -> R.string.bus422
- 305 -> R.string.bus441
- 306 -> R.string.bus442
- 307 -> R.string.bus451
- 308 -> R.string.bus452
- 309 -> R.string.bus481
- 310 -> R.string.bus482
- 311 -> R.string.bus491
- 312 -> R.string.bus492
- 313 -> R.string.bus501
- 314 -> R.string.bus502
- 315 -> R.string.bus511
- 316 -> R.string.bus512
- 317 -> R.string.bus521
- 318 -> R.string.bus522
-
- 401 -> R.string.buss1
- 402 -> R.string.buss2
- 403 -> R.string.buss3
- 404 -> R.string.buss4
- else -> throw IllegalArgumentException("Illegal lineId $lineId")
- }
-
- fun getTimetableTitleAsOnPrometWebsite(lineId: Int): String =
- when (lineId) {
- // Gradski
- 1 -> "3 BRNIK"
- 2 -> "3A BRNIK"
- 3 -> "6 KILA"
- 4 -> "7 ŽNJAN"
- 5 -> "7 ZAPADNA"
- 6 -> "8 ŽNJAN"
- 7 -> "8 ZVONČAC"
- 8 -> "9 RAVNE NJIVE"
- 9 -> "11 SPINUT"
- 10 -> "11 RAVNE"
- 11 -> "12 SV. FRANE"
- 12 -> "12 BENE"
- 13 -> "14 BRDA"
- 14 -> "14 DUILOVO"
- 15 -> "15 DUILOVO"
- 16 -> "17 SPINUT"
- 17 -> "17 TRSTENIK"
- 18 -> "18 SIROBUJA"
- 19 -> "20 BRDA"
- 20 -> "21 SV.FRANE"
- 21 -> "24 SPLIT"
- 22 -> "24 TTTS"
- 23 -> "25 SPLIT"
- 24 -> "25 STOBREČ"
- 25 -> "26 SPLIT"
- 26 -> "26 KAMEN"
- 27 -> "27 SPLIT"
- 28 -> "27 ŽRNOVNICA"
- 29 -> "39 LORA"
- 30 -> "40 TRAJ"
-
- // Urbano
- 101 -> "1 BUNJE"
- 102 -> "2 ZRAČN"
- 103 -> "2 SPLIT"
- 104 -> "2A"
- 105 -> "5 DRAČEVAC"
- 106 -> "5A DRAČEVAC"
- 107 -> "10 JAPIRKO"
- 108 -> "16 NINČEVIĆI"
- 109 -> "22 KLIS"
- 110 -> "23 HNK"
- 111 -> "28 SPLIT"
- 112 -> "28 DUBRAVA"
- 113 -> "29 SPLIT"
- 114 -> "29 NAKLICE"
- 115 -> "30 SPLIT"
- 116 -> "30 PODSTRANA"
- 117 -> "31 SPLIT"
- 118 -> "31 VRANJIC"
- 119 -> "32 SPLIT"
- 120 -> "32 KUČINE"
- 121 -> "33 SPLIT"
- 122 -> "33 K"
- 123 -> "34 SPLIT"
- 124 -> "34 KLIS"
- 125 -> "35 SPLIT"
- 126 -> "35 DU"
- 127 -> "36 SPLIT"
- 128 -> "36 KOPRIVNO"
- 129 -> "37 SP"
- 130 -> "37 TR"
- 131 -> "38 SPLIT"
- 132 -> "38 ZRAČNA"
- 133 -> "60 SPLIT"
- 134 -> "60 RAVNIČKI"
- 135 -> "ŽELJEZNIČKA STANICA - KAŠTEL STARI"
- 136 -> "KAŠTEL STARI - ŽELJEZNIČKA STANICA"
- 137 -> "TROGIR KOLODVOR - ŽELJEZNIČKA STANICA"
- 138 -> "ŽELJEZNIČKA STANICA (K. STARI) - TROGIR KOLODVOR INTEGRIRANA "
- 139 -> "TROGIR - SPLIT"
-
-
- // Prigradsko
- 201 -> "67 SPLIT"
- 202 -> "67 DOLAC"
- 203 -> "68 SPLIT"
- 204 -> "68 ŠEST"
- 205 -> "69 SPLIT"
- 206 -> "69 ŠEST"
- 207 -> "71 SPLIT"
- 208 -> "71 SUTINA"
- 209 -> "73 SPLIT"
- 210 -> "73 OGORJE"
- 211 -> "76 SPLIT"
- 212 -> "76 KLJACI"
- 213 -> "77 SPLIT"
- 214 -> "77 CRIVAC"
- 215 -> "80 SPLIT"
- 216 -> "80 DRNIŠ"
- 217 -> "81 SPLIT"
- 218 -> "81 NISKO"
- 219 -> "86 SPLIT"
- 220 -> "86 KLADNJICE"
- // 84
- // 85
- // 86
- 221 -> "90 SITNO"
- 222 -> "91 K"
- 223 -> "91 D"
- 224 -> "93 K"
- 225 -> "93 ŠE"
- 226 -> "KAŠTEL STARI - RUDINE"
- 227 -> "RUDINE - KAŠTEL STARI"
-
- // Trogir i Solta
- 301 -> "41 TROGIR"
- 302 -> "41 PLANO"
- 303 -> "42 TROGIR"
- 304 -> "42 SLATINE"
- 305 -> "44 TROGIR"
- 306 -> "44 OKRUG DONJI"
- 307 -> "45 TROGIR"
- 308 -> "45 SEGET"
- 309 -> "48 TROGIR"
- 310 -> "48 MARINA"
- 311 -> "49 TROGIR"
- 312 -> "49 VINIŠĆE"
- 313 -> "50 TROGIR"
- 314 -> "50 SEVID"
- 315 -> "51 TROGIR"
- 316 -> "51 LJUBITOVICA"
- 317 -> "52 TROGIR"
- 318 -> "52 VINOVAC"
-
- 401 -> "MASLINICA"
- 402 -> "ROGAČ - GROHOTE - SREDNJE SELO"
- 403 -> "STOMORSKA"
- 404 -> "ROGAČ - GROHOTE - NEČUJAM"
- else -> throw IllegalArgumentException("Illegal lineId $lineId")
- }
-
- companion object {
-
- const val AREA_CITY = 0
- const val AREA_URBAN = 1
- const val AREA_SUBURBAN = 2
- const val AREA_TROGIR = 4
- const val AREA_SOLTA = 5
-
- val list: List = listOf(
- // Gradski
- Timetable(1, "3", 31, AREA_CITY, 0, "", ""),
- Timetable(2, "3A", 32, AREA_CITY, 0, "", ""),
- Timetable(3, "6", 60, AREA_CITY, 0, "", ""),
- Timetable(4, "7", 71, AREA_CITY, 0, "", ""),
- Timetable(5, "7", 72, AREA_CITY, 0, "", ""),
- Timetable(6, "8", 81, AREA_CITY, 0, "", ""),
- Timetable(7, "8", 82, AREA_CITY, 0, "", ""),
- Timetable(8, "9", 90, AREA_CITY, 0, "", ""),
- Timetable(9, "11", 111, AREA_CITY, 0, "", ""),
- Timetable(10, "11", 112, AREA_CITY, 0, "", ""),
- Timetable(11, "12", 121, AREA_CITY, 0, "", ""),
- Timetable(12, "12", 122, AREA_CITY, 0, "", ""),
- Timetable(13, "14", 141, AREA_CITY, 0, "", ""),
- Timetable(14, "14", 142, AREA_CITY, 0, "", ""),
- Timetable(15, "15", 150, AREA_CITY, 0, "", ""),
- Timetable(16, "17", 171, AREA_CITY, 0, "", ""),
- Timetable(17, "17", 172, AREA_CITY, 0, "", ""),
- Timetable(18, "18", 180, AREA_CITY, 0, "", ""),
- Timetable(19, "20", 200, AREA_CITY, 0, "", ""),
- Timetable(20, "21", 210, AREA_CITY, 0, "", ""),
- Timetable(21, "24", 241, AREA_CITY, 0, "", ""),
- Timetable(22, "24", 242, AREA_CITY, 0, "", ""),
- Timetable(23, "25", 251, AREA_CITY, 0, "", ""),
- Timetable(24, "25", 252, AREA_CITY, 0, "", ""),
- Timetable(25, "26", 261, AREA_CITY, 0, "", ""),
- Timetable(26, "26", 262, AREA_CITY, 0, "", ""),
- Timetable(27, "27", 271, AREA_CITY, 0, "", ""),
- Timetable(28, "27", 272, AREA_CITY, 0, "", ""),
- Timetable(29, "39", 390, AREA_CITY, 0, "", ""),
- Timetable(30, "40", 400, AREA_CITY, 0, "", ""),
-
- // Urbano
- Timetable(101, "1", 10, AREA_URBAN, 0, "", ""),
- Timetable(102, "2", 21, AREA_URBAN, 0, "", ""),
- Timetable(103, "2", 22, AREA_URBAN, 0, "", ""),
- Timetable(104, "2A", 23, AREA_URBAN, 0, "", ""),
- Timetable(105, "5", 50, AREA_URBAN, 0, "", ""),
- Timetable(106, "5A", 51, AREA_URBAN, 0, "", ""),
- Timetable(107, "10", 100, AREA_URBAN, 0, "", ""),
- Timetable(108, "16", 160, AREA_URBAN, 0, "", ""),
- Timetable(109, "22", 220, AREA_URBAN, 0, "", ""),
- Timetable(110, "23", 230, AREA_URBAN, 0, "", ""),
- Timetable(111, "28", 281, AREA_URBAN, 0, "", ""),
- Timetable(112, "28", 282, AREA_URBAN, 0, "", ""),
- Timetable(113, "29", 291, AREA_URBAN, 0, "", ""),
- Timetable(114, "29", 292, AREA_URBAN, 0, "", ""),
- Timetable(115, "30", 301, AREA_URBAN, 0, "", ""),
- Timetable(116, "30", 302, AREA_URBAN, 0, "", ""),
- Timetable(117, "31", 311, AREA_URBAN, 0, "", ""),
- Timetable(118, "31", 312, AREA_URBAN, 0, "", ""),
- Timetable(119, "32", 321, AREA_URBAN, 0, "", ""),
- Timetable(120, "32", 322, AREA_URBAN, 0, "", ""),
- Timetable(121, "33", 331, AREA_URBAN, 0, "", ""),
- Timetable(122, "33", 332, AREA_URBAN, 0, "", ""),
- Timetable(123, "34", 341, AREA_URBAN, 0, "", ""),
- Timetable(124, "34", 342, AREA_URBAN, 0, "", ""),
- Timetable(125, "35", 351, AREA_URBAN, 0, "", ""),
- Timetable(126, "35", 352, AREA_URBAN, 0, "", ""),
- Timetable(127, "36", 361, AREA_URBAN, 0, "", ""),
- Timetable(128, "36", 362, AREA_URBAN, 0, "", ""),
- Timetable(129, "37", 371, AREA_URBAN, 0, "", ""),
- Timetable(130, "37", 372, AREA_URBAN, 0, "", ""),
- Timetable(131, "38", 381, AREA_URBAN, 0, "", ""),
- Timetable(132, "38", 382, AREA_URBAN, 0, "", ""),
- Timetable(133, "60", 601, AREA_URBAN, 0, "", ""),
- Timetable(134, "60", 602, AREA_URBAN, 0, "", ""),
- Timetable(135, "", 1000, AREA_URBAN, 0, "", ""),
- Timetable(136, "", 1001, AREA_URBAN, 0, "", ""),
- Timetable(137, "", 1002, AREA_URBAN, 0, "", ""),
- Timetable(138, "", 1003, AREA_URBAN, 0, "", ""),
- Timetable(139, "", 1004, AREA_URBAN, 0, "", ""),
-
- // Prigradsko
- Timetable(201, "67", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(202, "67", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(203, "68", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(204, "68", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(205, "69", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(206, "69", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(207, "71", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(208, "71", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(209, "73", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(210, "73", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(211, "76", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(212, "76", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(213, "77", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(214, "77", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(215, "80", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(216, "80", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(217, "81", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(218, "81", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(219, "86", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(220, "86", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(221, "90", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(222, "91", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(223, "91", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(224, "93", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(225, "93", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(226, "", 9999, AREA_SUBURBAN, 0, "", ""),
- Timetable(227, "", 9999, AREA_SUBURBAN, 0, "", ""),
-
- // Trogir i Solta
- Timetable(301, "41", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(302, "41", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(303, "42", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(304, "42", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(305, "44", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(306, "44", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(307, "45", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(308, "45", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(309, "48", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(310, "48", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(311, "49", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(312, "49", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(313, "50", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(314, "50", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(315, "51", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(316, "51", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(317, "52", 9999, AREA_TROGIR, 0, "", ""),
- Timetable(318, "52", 9999, AREA_TROGIR, 0, "", ""),
-
- Timetable(401, "", 9999, AREA_SOLTA, 0, "", ""),
- Timetable(402, "", 9999, AREA_SOLTA, 0, "", ""),
- Timetable(403, "", 9999, AREA_SOLTA, 0, "", ""),
- Timetable(404, "", 9999, AREA_SOLTA, 0, "", "")
- )
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/LocalModules.kt b/app/src/main/java/com/am/stbus/common/di/AppModule.kt
similarity index 69%
rename from app/src/main/java/com/am/stbus/common/di/LocalModules.kt
rename to app/src/main/java/com/am/stbus/common/di/AppModule.kt
index 7ed0caf..f0f4e33 100644
--- a/app/src/main/java/com/am/stbus/common/di/LocalModules.kt
+++ b/app/src/main/java/com/am/stbus/common/di/AppModule.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,28 +25,29 @@
package com.am.stbus.common.di
import androidx.room.Room
-import com.am.stbus.data.local.AppDatabase
-import org.koin.android.ext.koin.androidApplication
+import com.am.stbus.common.room.AppDatabase
+import com.am.stbus.data.ApiService
+import com.am.stbus.data.room.FavouriteItemDao
+import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
+import retrofit2.Retrofit
-val localModules = module {
+val appModule = module {
- single {
- Room.databaseBuilder(
- androidApplication(),
- AppDatabase::class.java,
- "split-bus-db"
- ).fallbackToDestructiveMigration().build()
+ single {
+ get().create(ApiService::class.java)
}
- single {
- get().newsDao()
+ single {
+ Room.databaseBuilder(
+ androidContext(),
+ AppDatabase::class.java, "split-bus-db"
+ ).build()
}
- single {
- get().timetableDao()
+ single {
+ get().favouriteItemDao()
}
-}
-
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/NetworkModule.kt b/app/src/main/java/com/am/stbus/common/di/NetworkModule.kt
new file mode 100644
index 0000000..34ee6d6
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/common/di/NetworkModule.kt
@@ -0,0 +1,56 @@
+package com.am.stbus.common.di
+
+import com.am.stbus.common.Constants.PROMET_API_URL
+import com.am.stbus.common.PROMET_KEY
+import kotlinx.serialization.json.Json
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.OkHttpClient
+import org.koin.dsl.module
+import retrofit2.Retrofit
+import retrofit2.converter.kotlinx.serialization.asConverterFactory
+import java.util.concurrent.TimeUnit
+
+val networkModule = module {
+
+ single {
+ Json {
+ ignoreUnknownKeys = true
+ isLenient = true
+ }
+ }
+
+ // Provide OkHttpClient
+ single {
+ OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ .addInterceptor { chain ->
+ //return response
+ chain.proceed(
+ //create request
+ chain.request()
+ .newBuilder()
+ .also {
+ it.addHeader("accept", "application/json, text/plain, */*")
+ it.addHeader("appuid", "PrometSplit.Mobile")
+ it.addHeader("x-auth-key", PROMET_KEY)
+ it.addHeader("x-tenant", "KingICT.PS.Public")
+ }.build()
+ )
+ }.build()
+ }
+
+ single {
+ Retrofit.Builder()
+ .baseUrl(PROMET_API_URL)
+ .client(get())
+ .addConverterFactory(
+ Json.asConverterFactory(
+ "application/json; charset=UTF8".toMediaType()
+ )
+ )
+ .build()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/NetworkModules.kt b/app/src/main/java/com/am/stbus/common/di/RepositoryModule.kt
similarity index 80%
rename from app/src/main/java/com/am/stbus/common/di/NetworkModules.kt
rename to app/src/main/java/com/am/stbus/common/di/RepositoryModule.kt
index e696ced..c6ff46a 100644
--- a/app/src/main/java/com/am/stbus/common/di/NetworkModules.kt
+++ b/app/src/main/java/com/am/stbus/common/di/RepositoryModule.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,18 +24,20 @@
package com.am.stbus.common.di
-import com.am.stbus.data.network.RemoteNewsDataSource
-import com.am.stbus.data.network.RemoteTimetableDataSource
+import com.am.stbus.domain.repositories.PrometApiRepository
+import com.am.stbus.domain.repositories.TimetablesRepository
import org.koin.dsl.module
-val networkModules = module {
+val repositoryModule = module {
single {
- RemoteNewsDataSource()
+ PrometApiRepository(
+ apiService = get()
+ )
}
single {
- RemoteTimetableDataSource()
+ TimetablesRepository()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/UseCaseModule.kt b/app/src/main/java/com/am/stbus/common/di/UseCaseModule.kt
index 04f6dcf..e74b72a 100644
--- a/app/src/main/java/com/am/stbus/common/di/UseCaseModule.kt
+++ b/app/src/main/java/com/am/stbus/common/di/UseCaseModule.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,35 +24,28 @@
package com.am.stbus.common.di
-import com.am.stbus.domain.usecases.news.NewsDetailUseCase
-import com.am.stbus.domain.usecases.news.NewsListUseCase
-import com.am.stbus.domain.usecases.timetables.TimetableDetailUseCase
-import com.am.stbus.domain.usecases.timetables.TimetableListUseCase
+import com.am.stbus.domain.usecases.FavouritesRoomDbUseCase
+import com.am.stbus.domain.usecases.GetBusStopArrivalsUseCase
+import com.am.stbus.domain.usecases.GetTimetableDetailDataUseCase
import org.koin.dsl.module
val useCaseModule = module {
- factory {
- NewsListUseCase(
- newsRepository = get()
+ single {
+ GetBusStopArrivalsUseCase(
+ prometApiRepository = get()
)
}
- factory {
- NewsDetailUseCase(
- newsRepository = get()
+ single {
+ GetTimetableDetailDataUseCase(
+ timetablesRepository = get()
)
}
- factory {
- TimetableListUseCase(
- timetableRepository = get()
- )
- }
-
- factory {
- TimetableDetailUseCase(
- timetableRepository = get()
+ single {
+ FavouritesRoomDbUseCase(
+ favouriteItemDao = get()
)
}
diff --git a/app/src/main/java/com/am/stbus/common/di/ViewModelModule.kt b/app/src/main/java/com/am/stbus/common/di/ViewModelModule.kt
index d1ffc8d..40e07c2 100644
--- a/app/src/main/java/com/am/stbus/common/di/ViewModelModule.kt
+++ b/app/src/main/java/com/am/stbus/common/di/ViewModelModule.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,66 +24,29 @@
package com.am.stbus.common.di
-import com.am.stbus.presentation.screens.favourites.FavouritesViewModel
-import com.am.stbus.presentation.screens.information.InformationListViewModel
-import com.am.stbus.presentation.screens.information.informationNewsListFragment.InformationNewsListViewModel
-import com.am.stbus.presentation.screens.information.informationNewsListFragment.informationNewsDetailFragment.InformationNewsDetailViewModel
-import com.am.stbus.presentation.screens.timetables.TimetablesSharedViewModel
-import com.am.stbus.presentation.screens.timetables.TimetablesViewModel
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.TimetablesListViewModel
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.timetableDetailFragment.TimetableDetailFragmentArgs
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.timetableDetailFragment.TimetableDetailViewModel
-import org.koin.androidx.viewmodel.dsl.viewModel
+import com.am.stbus.presentation.MainViewModel
+import com.am.stbus.presentation.screens.stops.detail.BusStopArrivalsDetailViewModel
+import com.am.stbus.presentation.screens.timetables.detail.TimetablesDetailViewModel
+import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module
-val viewModelModule = module{
+val viewModelModule = module {
viewModel {
- InformationListViewModel(
+ MainViewModel(
+ favouritesRoomDbUseCase = get()
)
}
viewModel {
- FavouritesViewModel(
- timetableListUseCase = get()
+ BusStopArrivalsDetailViewModel(
+ getDeparturesUseCase = get()
)
}
viewModel {
- TimetablesViewModel(
- timetableListUseCase = get()
+ TimetablesDetailViewModel(
+ getTimetableDetailDataUseCase = get()
)
}
-
- viewModel {
- TimetablesListViewModel(
- timetableListUseCase = get()
- )
- }
-
- viewModel {(args: TimetableDetailFragmentArgs) ->
- TimetableDetailViewModel(
- args = args,
- timetableListUseCase = get(),
- timetableDetailUseCase = get()
- )
- }
-
- viewModel {
- InformationNewsListViewModel(
- getNewsListUseCase = get()
- )
- }
-
- viewModel {(url: String) ->
- InformationNewsDetailViewModel(
- url = url,
- getNewsDetailUseCase = get()
- )
- }
-
- viewModel {
- TimetablesSharedViewModel()
- }
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/extensions/CommonExtensions.kt b/app/src/main/java/com/am/stbus/common/extensions/CommonExtensions.kt
deleted file mode 100644
index f751eb3..0000000
--- a/app/src/main/java/com/am/stbus/common/extensions/CommonExtensions.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.common.extensions
-
-import android.content.Context
-import android.content.Intent
-import android.content.res.Resources
-import android.net.Uri
-import android.os.Build
-import com.am.stbus.BuildConfig
-import com.am.stbus.common.Constants.PROMET_URL
-
-fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
-fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
-
-fun Context.loadUrl(url: String) = startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
-
-fun Context.loadPrometUrl() = this.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(PROMET_URL)))
-fun Context.loadEmailReport(linija: String, error: String) = this.startActivity(
- Intent.createChooser(
- Intent(
- Intent.ACTION_SENDTO,
- Uri.fromParts("mailto", "antoniomarinnn@gmail.com", null)
- ).apply {
- putExtra(Intent.EXTRA_SUBJECT, "Split Bus")
- putExtra(
- Intent.EXTRA_TEXT,
- "Molimo opisite problem!(Please describe your issue!)" +
- "\n\n\n\nInformacije o uredaju \n --------------------------------" +
- "\n Linija: $linija \n Split Bus verzija: ${BuildConfig.VERSION_NAME}" +
- "\n Greska: $error" +
- "\n Android: ${Build.VERSION.RELEASE} (SDK: ${Build.VERSION.SDK_INT})" +
- "\n Telefon: ${Build.MODEL} (Uredaj: ${Build.DEVICE})"
- )
- }, "Email"
- )
-)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/extensions/ViewExtensions.kt b/app/src/main/java/com/am/stbus/common/extensions/ViewExtensions.kt
deleted file mode 100644
index 471b410..0000000
--- a/app/src/main/java/com/am/stbus/common/extensions/ViewExtensions.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.common.extensions
-
-import android.app.Activity
-import android.os.Build
-import android.text.Spanned
-import android.view.View
-import androidx.core.content.ContextCompat
-import androidx.core.text.HtmlCompat
-import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
-
-fun View.systemUiVisibilityFullScreen() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
- }
-}
-
-fun Activity.changeStatusBarColor(colorId: Int) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- this.window.statusBarColor = ContextCompat.getColor(this, colorId)
- }
-}
-
-fun String.toSpanned(): Spanned {
- return HtmlCompat.fromHtml(this, FROM_HTML_MODE_LEGACY)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/local/AppDatabase.kt b/app/src/main/java/com/am/stbus/common/room/AppDatabase.kt
similarity index 75%
rename from app/src/main/java/com/am/stbus/data/local/AppDatabase.kt
rename to app/src/main/java/com/am/stbus/common/room/AppDatabase.kt
index 13234da..fa6b585 100644
--- a/app/src/main/java/com/am/stbus/data/local/AppDatabase.kt
+++ b/app/src/main/java/com/am/stbus/common/room/AppDatabase.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,16 +22,15 @@
* SOFTWARE.
*/
-package com.am.stbus.data.local
+package com.am.stbus.common.room
import androidx.room.Database
import androidx.room.RoomDatabase
-import com.am.stbus.common.Constants
-import com.am.stbus.domain.models.NewsListItem
-import com.am.stbus.domain.models.Timetable
+import com.am.stbus.common.Constants.DB_VERSION
+import com.am.stbus.data.models.FavouriteItem
+import com.am.stbus.data.room.FavouriteItemDao
-@Database(entities = [NewsListItem::class, Timetable::class], version = Constants.DB_VERSION, exportSchema = false)
+@Database(entities = [FavouriteItem::class], version = DB_VERSION)
abstract class AppDatabase : RoomDatabase() {
- abstract fun newsDao(): NewsDao
- abstract fun timetableDao(): TimetableDao
-}
+ abstract fun favouriteItemDao(): FavouriteItemDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/ApiService.kt b/app/src/main/java/com/am/stbus/data/ApiService.kt
new file mode 100644
index 0000000..eeeb678
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/data/ApiService.kt
@@ -0,0 +1,16 @@
+package com.am.stbus.data
+
+import com.am.stbus.data.models.BusStopArrival
+import retrofit2.Response
+import retrofit2.http.GET
+import retrofit2.http.Path
+
+interface ApiService {
+
+ @GET("stop/{busStopId}/arrival-times")
+ suspend fun getBusStopArrivals(
+ @Path(value = "busStopId") busStopId: Int
+ ): Response>
+
+}
+
diff --git a/app/src/main/java/com/am/stbus/data/Model.kt b/app/src/main/java/com/am/stbus/data/Model.kt
new file mode 100644
index 0000000..35045ab
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/data/Model.kt
@@ -0,0 +1,25 @@
+package com.am.stbus.data
+
+/* @SerialName("pathwayId")
+ val pathwayId: Int?,
+ @SerialName("transportServiceRouteId")
+ val transportServiceRouteId: Int?,
+ @SerialName("transportServiceRouteTripId")
+ val transportServiceRouteTripId: Int?,
+ @SerialName("publicName")
+ val publicName: String?,
+ @SerialName("name")
+ val name: String?,
+ @SerialName("serviceCalendarId")
+ val serviceCalendarId: Int?,
+ @SerialName("departureTime")
+ val departureTime: String?,
+ @SerialName("isActive")
+ val isActive: Boolean?
+)
+
+"departureTime": "23:54:00",
+"transportServiceRouteTripId": 21933498,
+"transportServiceRouteId": 83874,
+"transportServiceRouteCode": "60"
+*/
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/local/NewsDao.kt b/app/src/main/java/com/am/stbus/data/local/NewsDao.kt
deleted file mode 100644
index 3a2c6b4..0000000
--- a/app/src/main/java/com/am/stbus/data/local/NewsDao.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.local
-
-import androidx.room.*
-import com.am.stbus.domain.models.NewsListItem
-
-@Dao
-interface NewsDao {
- @Query("SELECT * FROM newsListItem")
- suspend fun getAll(): List
-
- @Query("SELECT * FROM newsListItem WHERE newsId IN (:newsIds)")
- suspend fun loadAllByIds(newsIds: IntArray): List
-
- @Query("SELECT * FROM newsListItem WHERE url LIKE :url LIMIT 1")
- suspend fun findByUrl(url: String): NewsListItem
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- suspend fun insertAll(news: List)
-
- @Delete
- suspend fun delete(news: NewsListItem)
-
- @Query("DELETE FROM newsListItem")
- suspend fun nukeTable()
-}
diff --git a/app/src/main/java/com/am/stbus/data/local/TimetableDao.kt b/app/src/main/java/com/am/stbus/data/local/TimetableDao.kt
deleted file mode 100644
index d1da574..0000000
--- a/app/src/main/java/com/am/stbus/data/local/TimetableDao.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.local
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import com.am.stbus.domain.models.Timetable
-import io.reactivex.Completable
-import io.reactivex.Single
-
-@Dao
-interface TimetableDao {
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertAll(news: List): Completable
-
- @Query("SELECT * FROM timetable")
- fun getAll(): Single>
-
- @Query("SELECT * FROM timetable WHERE lineId LIKE :lineId LIMIT 1")
- fun loadItemByLineId(lineId: Int): List
-
- @Query("SELECT * FROM timetable WHERE area_id LIKE :areaId LIMIT 1")
- fun loadItemsByAreaId(areaId: Int): List
-
- @Query("SELECT * FROM timetable WHERE favourite IS 1")
- fun loadFavourites(): List
-
- @Query("UPDATE timetable SET favourite = :favourite WHERE lineId LIKE :lineId ")
- fun setFavouriteToLineId(lineId: Int, favourite: Int): Completable
-
- @Query("UPDATE timetable SET content = :content, content_date = :contentDate WHERE lineId LIKE :lineId ")
- fun setTimetableContentToLineId(lineId: Int, content: String, contentDate: String): Completable
-
-}
diff --git a/app/src/main/java/com/am/stbus/domain/models/Notification.kt b/app/src/main/java/com/am/stbus/data/models/BusLine.kt
similarity index 81%
rename from app/src/main/java/com/am/stbus/domain/models/Notification.kt
rename to app/src/main/java/com/am/stbus/data/models/BusLine.kt
index a6faa5a..4d00a4a 100644
--- a/app/src/main/java/com/am/stbus/domain/models/Notification.kt
+++ b/app/src/main/java/com/am/stbus/data/models/BusLine.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,16 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.models
+package com.am.stbus.data.models
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class BusLine(
+ val id: Int,
+ val title: Int,
+ val number: String,
+ val websiteTitle: String
+)
+
-data class Notification(val id: Int, val notificationTitle: String, val notificationMessage: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/models/BusLineArea.kt b/app/src/main/java/com/am/stbus/data/models/BusLineArea.kt
new file mode 100644
index 0000000..238b801
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/data/models/BusLineArea.kt
@@ -0,0 +1,76 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.data.models
+
+import com.am.stbus.R
+import com.am.stbus.common.Constants.AREA_CITY_URL
+import com.am.stbus.common.Constants.AREA_SOLTA_URL
+import com.am.stbus.common.Constants.AREA_SUBURBAN_URL
+import com.am.stbus.common.Constants.AREA_TROGIR_URL
+import com.am.stbus.common.Constants.AREA_URBAN_URL
+import kotlinx.serialization.Serializable
+
+@Serializable
+sealed class BusLineArea {
+ @Serializable
+ object City : BusLineArea()
+
+ @Serializable
+ object Urban : BusLineArea()
+
+ @Serializable
+ object Suburban : BusLineArea()
+
+ @Serializable
+ object Trogir : BusLineArea()
+
+ @Serializable
+ object Solta : BusLineArea()
+
+ companion object {
+ fun BusLineArea.getPagerTitle(): Int {
+ return when (this) {
+ City -> R.string.timetables_area_city
+ Urban -> R.string.timetables_area_urban
+ Suburban -> R.string.timetables_area_suburban
+ Trogir -> R.string.timetables_area_trogir
+ Solta -> R.string.timetables_area_solta
+ }
+ }
+
+ fun BusLineArea.getBaseUrl(): String {
+ return when (this) {
+ City -> AREA_CITY_URL
+ Urban -> AREA_URBAN_URL
+ Suburban -> AREA_SUBURBAN_URL
+ Trogir -> AREA_TROGIR_URL
+ Solta -> AREA_SOLTA_URL
+ }
+ }
+ }
+}
+
+
+
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListViewModel.kt b/app/src/main/java/com/am/stbus/data/models/BusStop.kt
similarity index 85%
rename from app/src/main/java/com/am/stbus/presentation/screens/information/InformationListViewModel.kt
rename to app/src/main/java/com/am/stbus/data/models/BusStop.kt
index 77149b9..b92739c 100644
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListViewModel.kt
+++ b/app/src/main/java/com/am/stbus/data/models/BusStop.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,10 +22,14 @@
* SOFTWARE.
*/
-package com.am.stbus.presentation.screens.information
+package com.am.stbus.data.models
-import androidx.lifecycle.ViewModel
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class BusStop(
+ val id: Int,
+ val title: Int,
+)
-class InformationListViewModel() : ViewModel() {
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/models/NewsItem.kt b/app/src/main/java/com/am/stbus/data/models/BusStopArrival.kt
similarity index 75%
rename from app/src/main/java/com/am/stbus/domain/models/NewsItem.kt
rename to app/src/main/java/com/am/stbus/data/models/BusStopArrival.kt
index 8569eda..6e2a22f 100644
--- a/app/src/main/java/com/am/stbus/domain/models/NewsItem.kt
+++ b/app/src/main/java/com/am/stbus/data/models/BusStopArrival.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,9 +22,17 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.models
+package com.am.stbus.data.models
-data class NewsItem (
- val newsItemContent: String,
- val newsItemImageUrl: String
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class BusStopArrival(
+ @SerialName("lineNumber")
+ val lineNumber: String?,
+ @SerialName("title")
+ val title: String?,
+ @SerialName("time")
+ val time: String?,
)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/models/NewsListItem.kt b/app/src/main/java/com/am/stbus/data/models/FavouriteItem.kt
similarity index 77%
rename from app/src/main/java/com/am/stbus/domain/models/NewsListItem.kt
rename to app/src/main/java/com/am/stbus/data/models/FavouriteItem.kt
index 41622c1..cae70ab 100644
--- a/app/src/main/java/com/am/stbus/domain/models/NewsListItem.kt
+++ b/app/src/main/java/com/am/stbus/data/models/FavouriteItem.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,16 +22,15 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.models
+package com.am.stbus.data.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
-data class NewsListItem(
- @PrimaryKey val newsId: Int,
- @ColumnInfo(name = "title") val title: String,
- @ColumnInfo(name = "desc") val desc: String,
- @ColumnInfo(name = "date") val date: String,
- @ColumnInfo(name = "url") val url: String)
\ No newline at end of file
+data class FavouriteItem(
+ @PrimaryKey(autoGenerate = true) val uid: Long = 0,
+ @ColumnInfo(name = "id") val id: Int,
+ @ColumnInfo(name = "type") val type: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/network/RemoteNewsDataSource.kt b/app/src/main/java/com/am/stbus/data/network/RemoteNewsDataSource.kt
deleted file mode 100644
index fd4fc18..0000000
--- a/app/src/main/java/com/am/stbus/data/network/RemoteNewsDataSource.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.network
-
-import com.am.stbus.common.Constants
-import com.am.stbus.domain.models.NewsItem
-import com.am.stbus.domain.models.NewsListItem
-import io.reactivex.Single
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.withContext
-import org.jsoup.Jsoup
-import timber.log.Timber
-
-class RemoteNewsDataSource {
-
- suspend fun getNewsList(dispatcher: CoroutineDispatcher): List {
- return withContext(dispatcher) {
- try {
- val doc = Jsoup.connect(Constants.PROMET_NOVOSTI_URL).timeout(Constants.NETWORK_REQUEST_TIMEOUT).get()
- val newsList = mutableListOf()
- var count = 0
- val elements = doc.select("h3.c-article-card__title > a")
-
- for (e in elements) {
-
- val title = e.text()
- val url = e.attr("href")
-
- var summary = ""
- var datum: String
-
- doc.apply {
- datum = select("div.c-article-card__date")[count].text()
- val summaryElement = select("div.c-article-card__content")[count]
- val summaryElementSize = summaryElement.select("div.c-article-card__summary").size
- if (summaryElementSize > 0)
- summary = summaryElement.child(2).text()
-
- }
-
- newsList.add(NewsListItem(count, title, summary, datum, url))
- count += 1
- }
-
- newsList
- } catch (e: Exception) {
- Timber.e("Error fetching content")
- emptyList()
- }
- }
- }
-
- fun getNewsDetail(url: String): Single {
- return Single.fromCallable {
-
- val doc = Jsoup.connect(url).timeout(Constants.NETWORK_REQUEST_TIMEOUT).get()
- var newsImgUrl: String
- val newsContentWithAttachments: String
-
- doc.apply {
- val newsContent = if (select("[class=c-article-detail__body c-text-body]").size > 0) {
- select("[class=c-article-detail__body c-text-body]").html()
- } else {
- select("[class=EDN_article_content]").html()
- }
-
- val ul = doc.select("[class=o-list-bare c-article-document-list]").select("li")
- val attachments = ul.map {
- val attachmentUrl = it.select("[class=c-article-document o-media]").first()?.attr("href")
- val attachmentTitle = it.select("[class=c-article-document__title c-text-lead]").text()
- val attachmentProperties = it.select("[class=c-article-document__meta c-text-smallprint]").text()
- return@map "$attachmentTitle $attachmentProperties"
- }.joinToString(separator = "
")
-
- newsContentWithAttachments = newsContent + attachments
-
- newsImgUrl = "http://www.promet-split.hr${select("[class=c-gallery-fotorama__item c-gallery-fotorama__item--image js-gallery-unwrap]")
- .attr("data-img")}"
- }
-
- return@fromCallable NewsItem(newsContentWithAttachments, newsImgUrl)
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/network/RemoteTimetableDataSource.kt b/app/src/main/java/com/am/stbus/data/network/RemoteTimetableDataSource.kt
deleted file mode 100644
index b0d5f2b..0000000
--- a/app/src/main/java/com/am/stbus/data/network/RemoteTimetableDataSource.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.network
-
-import com.am.stbus.common.Constants
-import com.am.stbus.common.TimetablesData
-import io.reactivex.Single
-import org.jsoup.Jsoup
-import java.util.*
-import kotlin.collections.ArrayList
-
-class RemoteTimetableDataSource {
-
- fun getTimetableDetail(lineId: Int, url: String): Single {
- return Single.fromCallable {
-
- val timetableId = Jsoup.connect(url).timeout(Constants.NETWORK_REQUEST_TIMEOUT).get()
- .select(".c-vozni-red__search-select option:contains("
- + TimetablesData().getTimetableTitleAsOnPrometWebsite(lineId).toUpperCase(Locale.ROOT)
- + ")")
- .attr("value")
-
-
- val doc = Jsoup.connect(Constants.PROMET_URL + timetableId).timeout(Constants.NETWORK_REQUEST_TIMEOUT).get()
- val workDayList = ArrayList()
- val saturdayList = ArrayList()
- val sundayList = ArrayList()
-
- doc.apply {
- select("table.c-vozni-red__table td:eq(0)").let {
- for (e in it) {
- workDayList.add("\n ${e.text()}")
- }
- // dodgy fix za zadnji red :)
- workDayList.add("")
- }
-
- select("table.c-vozni-red__table td:eq(1)").let {
- for (e in it) {
- saturdayList.add("\n ${e.text()}")
- }
- saturdayList.add("")
- }
-
- select("table.c-vozni-red__table td:eq(2)").let {
- for (e in it) {
- sundayList.add("\n ${e.text()}")
- }
- sundayList.add("")
- }
- }
-
-
- val timetableItems = listOf(
- doc.select("h3.c-vozni-red__line").text(),
- doc.select("p.c-vozni-red__valid").text(),
- workDayList,
- saturdayList,
- sundayList,
- doc.select("div.c-vozni-red-note__items").text()
- )
-
- if (doc.select("p.c-vozni-red__valid").text().isNullOrBlank() && workDayList.isEmpty() && saturdayList.isEmpty() && sundayList.isEmpty()) {
- // Null response
- return@fromCallable ""
- } else {
- // Valid response
- return@fromCallable timetableItems.joinToString(Constants.EMA_DELIMITER)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/repositoriesImpl/NewsRepositoryImpl.kt b/app/src/main/java/com/am/stbus/data/repositoriesImpl/NewsRepositoryImpl.kt
deleted file mode 100644
index c8403eb..0000000
--- a/app/src/main/java/com/am/stbus/data/repositoriesImpl/NewsRepositoryImpl.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.repositoriesImpl
-
-import com.am.stbus.data.local.NewsDao
-import com.am.stbus.data.network.RemoteNewsDataSource
-import com.am.stbus.domain.models.NewsItem
-import com.am.stbus.domain.models.NewsListItem
-import com.am.stbus.domain.repositories.NewsRepository
-import io.reactivex.Single
-import kotlinx.coroutines.CoroutineDispatcher
-
-class NewsRepositoryImpl(
- private val remoteNewsDataSource: RemoteNewsDataSource,
- private val localNewsDataSource: NewsDao
-): NewsRepository {
- override suspend fun getNewsList(remote: Boolean, dispatcher: CoroutineDispatcher): List {
- return when(remote) {
- true -> remoteNewsDataSource.getNewsList(dispatcher)
- false -> localNewsDataSource.getAll()
- }
- }
-
- override suspend fun saveNewsList(list: List) {
- localNewsDataSource.insertAll(list)
- }
-
- override suspend fun deleteNewsList() {
- localNewsDataSource.nukeTable()
- }
-
- override fun getNewsDetail(remote: Boolean, url: String): Single {
- return when (remote) {
- true -> remoteNewsDataSource.getNewsDetail(url)
- false -> throw IllegalArgumentException("Shouldn't be here!")
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/repositoriesImpl/TimetableRepositoryImpl.kt b/app/src/main/java/com/am/stbus/data/repositoriesImpl/TimetableRepositoryImpl.kt
deleted file mode 100644
index 00d2a62..0000000
--- a/app/src/main/java/com/am/stbus/data/repositoriesImpl/TimetableRepositoryImpl.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.data.repositoriesImpl
-
-import com.am.stbus.data.local.TimetableDao
-import com.am.stbus.data.network.RemoteTimetableDataSource
-import com.am.stbus.domain.models.Timetable
-import com.am.stbus.domain.repositories.TimetableRepository
-import io.reactivex.Completable
-import io.reactivex.Single
-
-class TimetableRepositoryImpl(
- private val remoteTimetableDataSource: RemoteTimetableDataSource,
- private val localTimetableDataSource: TimetableDao
-): TimetableRepository {
-
- override fun saveTimetables(list: List): Completable {
- return localTimetableDataSource.insertAll(list)
- }
-
- override fun getTimetables(): Single> {
- return localTimetableDataSource.getAll()
- }
-
- override fun updateFavourites(lineId: Int, favourite: Int): Completable {
- return localTimetableDataSource.setFavouriteToLineId(lineId, favourite)
- }
-
- override fun getTimetableDetail(lineId: Int, url: String): Single{
- return remoteTimetableDataSource.getTimetableDetail(lineId, url)
- }
-
- override fun saveTimetableDetail(lineId: Int, content: String, contentDate: String): Completable {
- return localTimetableDataSource.setTimetableContentToLineId(lineId, content, contentDate)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/ApplicationModule.kt b/app/src/main/java/com/am/stbus/data/room/FavouriteItemDao.kt
similarity index 68%
rename from app/src/main/java/com/am/stbus/common/di/ApplicationModule.kt
rename to app/src/main/java/com/am/stbus/data/room/FavouriteItemDao.kt
index 1cc9d0f..c3a98b5 100644
--- a/app/src/main/java/com/am/stbus/common/di/ApplicationModule.kt
+++ b/app/src/main/java/com/am/stbus/data/room/FavouriteItemDao.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,15 +22,22 @@
* SOFTWARE.
*/
-package com.am.stbus.common.di
+package com.am.stbus.data.room
-import androidx.preference.PreferenceManager
-import org.koin.android.ext.koin.androidApplication
-import org.koin.dsl.module
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.Query
+import com.am.stbus.data.models.FavouriteItem
-val applicationModule = module {
+@Dao
+interface FavouriteItemDao {
+ @Query("SELECT * FROM favouriteitem")
+ suspend fun getAll(): List
+
+ @Insert
+ suspend fun insert(favouriteItem: FavouriteItem)
+
+ @Query("DELETE FROM FavouriteItem WHERE id = :id AND type = :type")
+ suspend fun delete(id: Int, type: Int)
- single {
- PreferenceManager.getDefaultSharedPreferences(androidApplication())
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/data/static/BusLinesData.kt b/app/src/main/java/com/am/stbus/data/static/BusLinesData.kt
new file mode 100644
index 0000000..0f5f8da
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/data/static/BusLinesData.kt
@@ -0,0 +1,143 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.data.static
+
+import com.am.stbus.R
+import com.am.stbus.data.models.BusLine
+
+val CITY_BUS_LINES = listOf(
+ BusLine(id = 1, title = R.string.bus3, number = "3", websiteTitle = "3 BRNIK"),
+ BusLine(id = 2, title = R.string.bus3A, number = "3A", websiteTitle = "3A BRNIK"),
+ BusLine(id = 3, title = R.string.bus6, number = "6", websiteTitle = "6 KILA"),
+ BusLine(id = 4, title = R.string.bus71, number = "7", websiteTitle = "7 ŽNJAN"),
+ BusLine(id = 5, title = R.string.bus72, number = "7", websiteTitle = "7 ZAPADNA"),
+ BusLine(id = 6, title = R.string.bus81, number = "8", websiteTitle = "8 ŽNJAN"),
+ BusLine(id = 7, title = R.string.bus82, number = "8", websiteTitle = "8 ZVONČAC"),
+ BusLine(id = 8, title = R.string.bus9, number = "9", websiteTitle = "9 RAVNE"),
+ BusLine(id = 9, title = R.string.bus111, number = "11", websiteTitle = "11 SPINUT"),
+ BusLine(id = 10, title = R.string.bus112, number = "11", websiteTitle = "11 RAVNE"),
+ BusLine(id = 11, title = R.string.bus121, number = "12", websiteTitle = "12 SV. FRANE"),
+ BusLine(id = 12, title = R.string.bus122, number = "12", websiteTitle = "12 BENE"),
+ BusLine(id = 13, title = R.string.bus131, number = "13", websiteTitle = "13 SPINUT"),
+ BusLine(id = 14, title = R.string.bus132, number = "13", websiteTitle = "13 DUILOVO"),
+ BusLine(id = 15, title = R.string.bus141, number = "14", websiteTitle = "14 BRDA"),
+ BusLine(id = 16, title = R.string.bus142, number = "14", websiteTitle = "14 ŽNJAN"),
+ BusLine(id = 17, title = R.string.bus15, number = "15", websiteTitle = "15 DUILOVO"),
+ BusLine(id = 18, title = R.string.bus171, number = "17", websiteTitle = "17 SPINUT"),
+ BusLine(id = 19, title = R.string.bus172, number = "17", websiteTitle = "17 TRSTENIK"),
+ BusLine(id = 20, title = R.string.bus18, number = "18", websiteTitle = "18 SIROBUJA"),
+ BusLine(id = 21, title = R.string.bus20, number = "20", websiteTitle = "20 BRDA"),
+ BusLine(id = 22, title = R.string.bus21, number = "21", websiteTitle = "21 SV.FRANE"),
+ BusLine(id = 23, title = R.string.bus241, number = "24", websiteTitle = "24 SPLIT"),
+ BusLine(id = 24, title = R.string.bus242, number = "24", websiteTitle = "24 TTTS"),
+ BusLine(id = 25, title = R.string.bus251, number = "25", websiteTitle = "25 SPLIT"),
+ BusLine(id = 26, title = R.string.bus252, number = "25", websiteTitle = "25 STOBREČ"),
+ BusLine(id = 27, title = R.string.bus261, number = "26", websiteTitle = "26 SPLIT"),
+ BusLine(id = 28, title = R.string.bus262, number = "26", websiteTitle = "26 KAMEN"),
+ BusLine(id = 29, title = R.string.bus271, number = "27", websiteTitle = "27 SPLIT"),
+ BusLine(id = 30, title = R.string.bus272, number = "27", websiteTitle = "27 ŽRNOVNICA")
+)
+
+val URBAN_AREA_BUS_LINES = listOf(
+ BusLine(id = 100, title = R.string.bus1, number = "1", websiteTitle = "1 BUNJE"),
+ BusLine(id = 101, title = R.string.bus021, number = "2", websiteTitle = "2 SPLIT"),
+ BusLine(id = 102, title = R.string.bus022, number = "2", websiteTitle = "2 ZRAČNA"),
+ BusLine(id = 103, title = R.string.bus2A, number = "2A", websiteTitle = "2A K.SUĆURAC"),
+ BusLine(id = 104, title = R.string.bus5, number = "5", websiteTitle = "5 DRAČEVAC"),
+ BusLine(id = 105, title = R.string.bus5A, number = "5A", websiteTitle = "5A DRAČEVAC"),
+ BusLine(id = 106, title = R.string.bus10, number = "10", websiteTitle = "10 JAPIRKO"),
+ BusLine(id = 107, title = R.string.bus16, number = "16", websiteTitle = "16 NINČEVIĆI"),
+ BusLine(id = 108, title = R.string.bus221, number = "22", websiteTitle = "22 SPLIT"),
+ BusLine(id = 109, title = R.string.bus222, number = "22", websiteTitle = "22 KLIS"),
+ BusLine(id = 110, title = R.string.bus281, number = "28", websiteTitle = "28 SPLIT"),
+ BusLine(id = 111, title = R.string.bus282, number = "28", websiteTitle = "28 DUBRAVA"),
+ BusLine(id = 112, title = R.string.bus291, number = "29", websiteTitle = "29 SPLIT"),
+ BusLine(id = 113, title = R.string.bus292, number = "29", websiteTitle = "29 NAKLICE"),
+ BusLine(id = 114, title = R.string.bus301, number = "30", websiteTitle = "30 SPLIT"),
+ BusLine(id = 115, title = R.string.bus302, number = "30", websiteTitle = "30 PODSTRANA"),
+ BusLine(id = 116, title = R.string.bus311, number = "31", websiteTitle = "31 SPLIT"),
+ BusLine(id = 117, title = R.string.bus312, number = "31", websiteTitle = "31 VRANJIC"),
+ BusLine(id = 118, title = R.string.bus321, number = "32", websiteTitle = "32 SPLIT"),
+ BusLine(id = 119, title = R.string.bus322, number = "32", websiteTitle = "32 KUČINE"),
+ BusLine(id = 120, title = R.string.bus331, number = "33", websiteTitle = "33 SPLIT"),
+ BusLine(id = 121, title = R.string.bus332, number = "33", websiteTitle = "33 KLIS"),
+ BusLine(id = 122, title = R.string.bus351, number = "35", websiteTitle = "35 SPLIT"),
+ BusLine(id = 123, title = R.string.bus352, number = "35", websiteTitle = "35 DUGOPOLJE"),
+ BusLine(id = 124, title = R.string.bus361, number = "36", websiteTitle = "36 SPLIT"),
+ BusLine(id = 125, title = R.string.bus362, number = "36", websiteTitle = "36 KOPRIVNO"),
+ BusLine(id = 126, title = R.string.bus371, number = "37", websiteTitle = "37 SPLIT"),
+ BusLine(id = 127, title = R.string.bus372, number = "37", websiteTitle = "37 TROGIR"),
+ BusLine(id = 128, title = R.string.bus381, number = "38", websiteTitle = "38 SPLIT"),
+ BusLine(id = 129, title = R.string.bus382, number = "38", websiteTitle = "38 ZRAČNA"),
+ BusLine(id = 130, title = R.string.bus601, number = "60", websiteTitle = "60 SPLIT"),
+ BusLine(id = 131, title = R.string.bus602, number = "60", websiteTitle = "60 RAVNIČKI"),
+ BusLine(id = 132, title = R.string.bus391, number = "39", websiteTitle = "39 KAŠTEL"),
+ BusLine(id = 133, title = R.string.bus392, number = "39", websiteTitle = "39 RUDINE"),
+ BusLine(id = 134, title = R.string.bus39A1, number = "39A", websiteTitle = "39A KAŠTEL"),
+ BusLine(id = 135, title = R.string.bus39A2, number = "39A", websiteTitle = "39A ŽELJEZNIČKA"),
+ BusLine(id = 136, title = R.string.trostdirekt, number = "", websiteTitle = "TROGIR")
+)
+
+val SUBURBAN_AREA_BUS_LINES = listOf(
+ BusLine(id = 500, title = R.string.bus671, number = "67", websiteTitle = "67 SPLIT"),
+ BusLine(id = 501, title = R.string.bus671, number = "67", websiteTitle = "67 DOLAC"),
+ BusLine(id = 502, title = R.string.bus681, number = "68", websiteTitle = "68 SPLIT"),
+ BusLine(id = 503, title = R.string.bus682, number = "68", websiteTitle = "68 ŠESTANOVAC"),
+ BusLine(id = 504, title = R.string.bus691, number = "69", websiteTitle = "69 SPLIT"),
+ BusLine(id = 505, title = R.string.bus692, number = "69", websiteTitle = "69 ŠESTANOVAC"),
+ BusLine(id = 506, title = R.string.bus701, number = "70", websiteTitle = "70 GRAB"),
+ BusLine(id = 507, title = R.string.bus702, number = "70", websiteTitle = "70 BISKO"),
+ BusLine(id = 508, title = R.string.bus711, number = "71", websiteTitle = "71 SPLIT"),
+ BusLine(id = 509, title = R.string.bus712, number = "71", websiteTitle = "71 SUTINA"),
+ BusLine(id = 510, title = R.string.bus731, number = "73", websiteTitle = "73 SPLIT"),
+ BusLine(id = 511, title = R.string.bus732, number = "73", websiteTitle = "73 OGORJE"),
+ BusLine(id = 512, title = R.string.bus761, number = "76", websiteTitle = "76 SPLIT"),
+ BusLine(id = 513, title = R.string.bus762, number = "76", websiteTitle = "76 KLJACI"),
+ BusLine(id = 514, title = R.string.bus771, number = "77", websiteTitle = "77 SPLIT"),
+ BusLine(id = 515, title = R.string.bus772, number = "77", websiteTitle = "77 CRIVAC"),
+ BusLine(id = 516, title = R.string.bus801, number = "80", websiteTitle = "80 SPLIT"),
+ BusLine(id = 517, title = R.string.bus802, number = "80", websiteTitle = "80 DRNIŠ"),
+ BusLine(id = 518, title = R.string.bus811, number = "81", websiteTitle = "81 SPLIT"),
+ BusLine(id = 519, title = R.string.bus812, number = "81", websiteTitle = "81 NISKO"),
+ BusLine(id = 520, title = R.string.bus861, number = "86", websiteTitle = "86 SPLIT"),
+ BusLine(id = 521, title = R.string.bus862, number = "86", websiteTitle = "86 KLADNJICE"),
+ BusLine(id = 522, title = R.string.bus900, number = "90", websiteTitle = "90 SITNO"),
+ BusLine(id = 523, title = R.string.bus911, number = "91", websiteTitle = "91 K.STARI"),
+ BusLine(id = 524, title = R.string.bus912, number = "91", websiteTitle = "91 DIVOJEVIĆI"),
+ BusLine(id = 525, title = R.string.bus931, number = "93", websiteTitle = "93 K.STARI"),
+ BusLine(id = 526, title = R.string.bus932, number = "93", websiteTitle = "93 ŠERIĆI")
+)
+
+
+val TROGIR_BUS_LINES = emptyList()
+
+val SOLTA_BUS_LINES = emptyList()
+
+val COMBINED_BUS_LINES =
+ CITY_BUS_LINES + URBAN_AREA_BUS_LINES + SUBURBAN_AREA_BUS_LINES + TROGIR_BUS_LINES + SOLTA_BUS_LINES
+
+fun findBusLinePerId(id: Int): BusLine? {
+ return COMBINED_BUS_LINES.firstOrNull { it.id == id }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/di/RepositoriesModule.kt b/app/src/main/java/com/am/stbus/data/static/BusStopsData.kt
similarity index 55%
rename from app/src/main/java/com/am/stbus/common/di/RepositoriesModule.kt
rename to app/src/main/java/com/am/stbus/data/static/BusStopsData.kt
index 8d9ad59..8088f4b 100644
--- a/app/src/main/java/com/am/stbus/common/di/RepositoriesModule.kt
+++ b/app/src/main/java/com/am/stbus/data/static/BusStopsData.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,28 +22,42 @@
* SOFTWARE.
*/
-package com.am.stbus.common.di
+package com.am.stbus.data.static
-import com.am.stbus.data.repositoriesImpl.NewsRepositoryImpl
-import com.am.stbus.data.repositoriesImpl.TimetableRepositoryImpl
-import com.am.stbus.domain.repositories.NewsRepository
-import com.am.stbus.domain.repositories.TimetableRepository
-import org.koin.dsl.module
+import com.am.stbus.R
+import com.am.stbus.data.models.BusStop
-val repositoriesModule = module {
-
- single {
- NewsRepositoryImpl(
- remoteNewsDataSource = get(),
- localNewsDataSource = get()
- )
- }
-
- single {
- TimetableRepositoryImpl(
- remoteTimetableDataSource = get(),
- localTimetableDataSource = get()
- )
- }
+val BUS_ARRIVALS_STOPS = listOf(
+ BusStop(
+ id = 675258,
+ title = R.string.bus_stop_hnk
+ ),
+ BusStop(
+ id = 676742,
+ title = R.string.bus_stop_hnk_izlaz
+ ),
+ BusStop(
+ id = 675289,
+ title = R.string.bus_stop_pazar_poljicka
+ ),
+ BusStop(
+ id = 675290,
+ title = R.string.bus_stop_pazar_opcina
+ ),
+ BusStop(
+ id = 675287,
+ title = R.string.bus_stop_opcina_poljicka
+ ),
+ BusStop(
+ id = 675286,
+ title = R.string.bus_stop_opcina_dom_rata
+ ),
+ BusStop(
+ id = 676393,
+ title = R.string.bus_stop_sukoišan
+ )
+)
+fun findBusStopArrivalPerId(id: Int): BusStop? {
+ return BUS_ARRIVALS_STOPS.firstOrNull { it.id == id }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/models/Information.kt b/app/src/main/java/com/am/stbus/domain/models/Information.kt
deleted file mode 100644
index ddebe6e..0000000
--- a/app/src/main/java/com/am/stbus/domain/models/Information.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.domain.models
-
-data class Information(val informationId: Int, val viewType: Int, val informationTitle: String, val informationDesc: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/models/Timetable.kt b/app/src/main/java/com/am/stbus/domain/models/Timetable.kt
deleted file mode 100644
index 3857495..0000000
--- a/app/src/main/java/com/am/stbus/domain/models/Timetable.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.domain.models
-
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity
-data class Timetable(
- @PrimaryKey val lineId: Int,
- @ColumnInfo(name = "line_number") val lineNumber: String,
- @ColumnInfo(name = "gmaps_id") val gmapsId: Int,
- @ColumnInfo(name = "area_id") val areaId: Int,
- @ColumnInfo(name = "favourite") var favourite: Int,
- @ColumnInfo(name = "content") var content: String,
- @ColumnInfo(name = "content_date") var contentDate: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/usecases/news/NewsDetailUseCase.kt b/app/src/main/java/com/am/stbus/domain/repositories/PrometApiRepository.kt
similarity index 72%
rename from app/src/main/java/com/am/stbus/domain/usecases/news/NewsDetailUseCase.kt
rename to app/src/main/java/com/am/stbus/domain/repositories/PrometApiRepository.kt
index 5f9b7de..e1e3712 100644
--- a/app/src/main/java/com/am/stbus/domain/usecases/news/NewsDetailUseCase.kt
+++ b/app/src/main/java/com/am/stbus/domain/repositories/PrometApiRepository.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,16 +22,17 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.usecases.news
+package com.am.stbus.domain.repositories
-import com.am.stbus.domain.models.NewsItem
-import com.am.stbus.domain.repositories.NewsRepository
-import io.reactivex.Single
+import com.am.stbus.data.ApiService
+import com.am.stbus.data.models.BusStopArrival
+import retrofit2.Response
-class NewsDetailUseCase(private val newsRepository: NewsRepository) {
-
- fun get(remote: Boolean, url: String): Single {
- return newsRepository.getNewsDetail(remote, url)
+class PrometApiRepository(
+ private val apiService: ApiService
+) {
+ suspend fun getBusStopArrivals(busStopId: Int): Response> {
+ return apiService.getBusStopArrivals(busStopId = busStopId)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/repositories/TimetableRepository.kt b/app/src/main/java/com/am/stbus/domain/repositories/TimetableRepository.kt
deleted file mode 100644
index 8847fd5..0000000
--- a/app/src/main/java/com/am/stbus/domain/repositories/TimetableRepository.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.domain.repositories
-
-import com.am.stbus.domain.models.Timetable
-import io.reactivex.Completable
-import io.reactivex.Single
-
-interface TimetableRepository {
- fun saveTimetables(list: List): Completable
- fun getTimetables(): Single>
- fun updateFavourites(lineId: Int, favourite: Int): Completable
- fun getTimetableDetail(lineId: Int, url: String): Single
- fun saveTimetableDetail(lineId: Int, content: String, contentDate: String): Completable
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/repositories/NewsRepository.kt b/app/src/main/java/com/am/stbus/domain/repositories/TimetablesRepository.kt
similarity index 54%
rename from app/src/main/java/com/am/stbus/domain/repositories/NewsRepository.kt
rename to app/src/main/java/com/am/stbus/domain/repositories/TimetablesRepository.kt
index 540524b..caeb703 100644
--- a/app/src/main/java/com/am/stbus/domain/repositories/NewsRepository.kt
+++ b/app/src/main/java/com/am/stbus/domain/repositories/TimetablesRepository.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,14 +24,34 @@
package com.am.stbus.domain.repositories
-import com.am.stbus.domain.models.NewsItem
-import com.am.stbus.domain.models.NewsListItem
-import io.reactivex.Single
-import kotlinx.coroutines.CoroutineDispatcher
+import com.am.stbus.common.Constants.NETWORK_REQUEST_TIMEOUT
+import com.am.stbus.common.Constants.PROMET_ALL_LINES_URL
+import com.am.stbus.common.Constants.PROMET_ALL_LINE_ID_URL
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Document
+
+class TimetablesRepository {
+
+ fun getTimetableId(websiteTitle: String): Int? {
+
+ val timetablePath =
+ Jsoup.connect(PROMET_ALL_LINES_URL).timeout(NETWORK_REQUEST_TIMEOUT).get()
+ .select(
+ ".c-vozni-red__search-select option:contains("
+ + websiteTitle
+ + ")"
+ )
+ .attr("value")
+
+ val timetableId = timetablePath.split("/").lastOrNull()?.toIntOrNull()
+
+ return timetableId
+ }
+
+ fun getTimetableForId(timetableId: Int): Document {
+ return Jsoup.connect(PROMET_ALL_LINE_ID_URL + timetableId)
+ .timeout(NETWORK_REQUEST_TIMEOUT).get()
+ }
+
-interface NewsRepository {
- suspend fun getNewsList(remote: Boolean, dispatcher: CoroutineDispatcher): List
- suspend fun saveNewsList(list: List)
- suspend fun deleteNewsList()
- fun getNewsDetail(remote: Boolean, url: String): Single
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableDetailUseCase.kt b/app/src/main/java/com/am/stbus/domain/usecases/FavouritesRoomDbUseCase.kt
similarity index 63%
rename from app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableDetailUseCase.kt
rename to app/src/main/java/com/am/stbus/domain/usecases/FavouritesRoomDbUseCase.kt
index 976c765..e8c0219 100644
--- a/app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableDetailUseCase.kt
+++ b/app/src/main/java/com/am/stbus/domain/usecases/FavouritesRoomDbUseCase.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,19 +22,28 @@
* SOFTWARE.
*/
-package com.am.stbus.domain.usecases.timetables
+package com.am.stbus.domain.usecases
-import com.am.stbus.domain.repositories.TimetableRepository
-import io.reactivex.Completable
-import io.reactivex.Single
+import com.am.stbus.data.models.FavouriteItem
+import com.am.stbus.data.room.FavouriteItemDao
-class TimetableDetailUseCase(private val timetableRepository: TimetableRepository) {
+class FavouritesRoomDbUseCase(
+ private val favouriteItemDao: FavouriteItemDao
+) {
+ suspend fun getAllTimetable(): List {
+ return favouriteItemDao.getAll()
+ }
- fun getTimetableDetail(lineId: Int, url: String): Single {
- return timetableRepository.getTimetableDetail(lineId, url)
+ suspend fun add(id: Int, type: Int) {
+ favouriteItemDao.insert(
+ FavouriteItem(
+ id = id,
+ type = type
+ )
+ )
}
- fun saveTimetableDetail(lineId: Int, content: String, contentDate: String): Completable {
- return timetableRepository.saveTimetableDetail(lineId, content, contentDate)
+ suspend fun remove(id: Int, type: Int) {
+ favouriteItemDao.delete(id, type)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/common/helpers/Event.kt b/app/src/main/java/com/am/stbus/domain/usecases/GetBusStopArrivalsUseCase.kt
similarity index 58%
rename from app/src/main/java/com/am/stbus/common/helpers/Event.kt
rename to app/src/main/java/com/am/stbus/domain/usecases/GetBusStopArrivalsUseCase.kt
index a8d9e70..c7785f2 100644
--- a/app/src/main/java/com/am/stbus/common/helpers/Event.kt
+++ b/app/src/main/java/com/am/stbus/domain/usecases/GetBusStopArrivalsUseCase.kt
@@ -1,7 +1,7 @@
/*
* MIT License
*
- * Copyright (c) 2013 - 2021 Antonio Marin
+ * Copyright (c) 2013 - 2025 Antonio Marin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,31 +22,29 @@
* SOFTWARE.
*/
-package com.am.stbus.common.helpers
+package com.am.stbus.domain.usecases
-/**
- * Used as a wrapper for data that is exposed via a LiveData that represents an event.
- */
-open class Event(private val content: T) {
-
- var hasBeenHandled = false
- private set // Allow external read but not write
+import com.am.stbus.data.models.BusStopArrival
+import com.am.stbus.domain.repositories.PrometApiRepository
+import timber.log.Timber
- /**
- * Returns the content and prevents its use again.
- */
- fun getContentIfNotHandled(action: (T) -> Unit) {
- if (!hasBeenHandled) {
- action(content)
- hasBeenHandled = true
- }
- }
+class GetBusStopArrivalsUseCase(
+ private val prometApiRepository: PrometApiRepository
+) {
+ suspend fun run(busStopId: Int): Result> {
+ return try {
+ val response = prometApiRepository.getBusStopArrivals(busStopId)
- /**
- * Returns the content, even if it's already been handled.
- */
- fun peekContent(): T = content
-}
+ Timber.d("Debugging - response $response")
-fun T.inEvent(): Event = Event(this)
+ if (response.isSuccessful) {
+ Result.success(response.body() ?: emptyList())
+ } else {
+ Result.failure(Exception("error"))
+ }
+ } catch (exp: Exception) {
+ Result.failure(Exception(exp))
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/usecases/GetTimetableDetailDataUseCase.kt b/app/src/main/java/com/am/stbus/domain/usecases/GetTimetableDetailDataUseCase.kt
new file mode 100644
index 0000000..c5e7ee9
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/domain/usecases/GetTimetableDetailDataUseCase.kt
@@ -0,0 +1,98 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.domain.usecases
+
+import com.am.stbus.domain.repositories.TimetablesRepository
+
+class GetTimetableDetailDataUseCase(
+ private val timetablesRepository: TimetablesRepository
+) {
+ fun run(websiteTitle: String): Result {
+ return try {
+
+ val timetableId = timetablesRepository.getTimetableId(websiteTitle)
+
+ if (timetableId == null) {
+ return Result.failure(Exception("Missing timetableId"))
+ }
+
+ val doc = timetablesRepository.getTimetableForId(timetableId)
+
+ val workDayList = mutableListOf>()
+ val saturdayList = mutableListOf>()
+ val sundayList = mutableListOf>()
+
+ val table = doc.select("table.c-vozni-red__table")
+
+ table.select("tbody tr").forEach { row ->
+ val cells = row.select("td")
+
+ // Column 0: Weekday
+ workDayList.add(
+ cells.getOrNull(0)
+ ?.select("span.c-vozni-red__box--new")?.map {
+ it.text()
+ } ?: emptyList()
+ )
+
+ // Column 1: Saturday
+ saturdayList.add(
+ cells.getOrNull(1)
+ ?.select("span.c-vozni-red__box--new")?.map {
+ it.text()
+ } ?: emptyList()
+ )
+
+ // Column 2: Sunday/Holiday
+ sundayList.add(
+ cells.getOrNull(2)
+ ?.select("span.c-vozni-red__box--new")?.map {
+ it.text()
+ } ?: emptyList()
+ )
+ }
+
+ Result.success(
+ TimetableDetailData(
+ validFrom = doc.select("p.c-vozni-red__valid").text(),
+ workdayItems = workDayList.toList(),
+ saturdayItems = saturdayList.toList(),
+ sundayList = sundayList.toList(),
+ notes = doc.select("div.c-vozni-red-note__items").text()
+ )
+ )
+ } catch (exp: Exception) {
+ Result.failure(exp)
+ }
+ }
+
+ data class TimetableDetailData(
+ val validFrom: String,
+ val workdayItems: List>,
+ val saturdayItems: List>,
+ val sundayList: List>,
+ val notes: String
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/usecases/news/NewsListUseCase.kt b/app/src/main/java/com/am/stbus/domain/usecases/news/NewsListUseCase.kt
deleted file mode 100644
index dd71346..0000000
--- a/app/src/main/java/com/am/stbus/domain/usecases/news/NewsListUseCase.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.domain.usecases.news
-
-import com.am.stbus.domain.models.NewsListItem
-import com.am.stbus.domain.repositories.NewsRepository
-import kotlinx.coroutines.CoroutineDispatcher
-
-class NewsListUseCase(private val newsRepository: NewsRepository) {
-
- suspend fun getLocalNewsList(
- dispatcher: CoroutineDispatcher
- ): List {
- return newsRepository.getNewsList(false, dispatcher)
- }
-
- suspend fun getRemoteNewsList(
- dispatcher: CoroutineDispatcher
- ): List {
- newsRepository.deleteNewsList()
- val list = newsRepository.getNewsList(true, dispatcher)
- newsRepository.saveNewsList(list)
- return list
- }
-
- suspend fun deleteNewsList() {
- newsRepository.deleteNewsList()
- }
-
- suspend fun save(list: List) {
- newsRepository.saveNewsList(list)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableListUseCase.kt b/app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableListUseCase.kt
deleted file mode 100644
index 19ca68e..0000000
--- a/app/src/main/java/com/am/stbus/domain/usecases/timetables/TimetableListUseCase.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.domain.usecases.timetables
-
-import com.am.stbus.domain.models.Timetable
-import com.am.stbus.domain.repositories.TimetableRepository
-import io.reactivex.Completable
-import io.reactivex.Single
-
-class TimetableListUseCase(private val timetableRepository: TimetableRepository) {
-
- fun saveTimetables(list: List): Completable {
- return timetableRepository.saveTimetables(list)
- }
-
- fun getTimetables(): Single> {
- return timetableRepository.getTimetables()
- }
-
- fun updateFavourites(lineId: Int, favourite: Int): Completable {
- return timetableRepository.updateFavourites(lineId, favourite)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/MainActivity.kt b/app/src/main/java/com/am/stbus/presentation/MainActivity.kt
new file mode 100644
index 0000000..ae3b2af
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/MainActivity.kt
@@ -0,0 +1,197 @@
+package com.am.stbus.presentation
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.DirectionsBus
+import androidx.compose.material.icons.filled.Home
+import androidx.compose.material.icons.rounded.DepartureBoard
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.Icon
+import androidx.compose.material3.NavigationBar
+import androidx.compose.material3.NavigationBarItem
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
+import androidx.navigation3.runtime.NavKey
+import androidx.navigation3.runtime.entryProvider
+import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
+import androidx.navigation3.ui.NavDisplay
+import com.am.stbus.data.models.BusLine
+import com.am.stbus.data.models.BusStop
+import com.am.stbus.presentation.screens.home.HomeScreen
+import com.am.stbus.presentation.screens.stops.detail.BusStopArrivalsDetailScreen
+import com.am.stbus.presentation.screens.stops.list.BusStopArrivalsListScreen
+import com.am.stbus.presentation.screens.timetables.detail.TimetablesDetailScreen
+import com.am.stbus.presentation.screens.timetables.list.TimetablesScreen
+import com.am.stbus.presentation.theme.SplitBusTheme
+import kotlinx.serialization.Serializable
+import org.koin.androidx.viewmodel.ext.android.viewModel
+
+class MainActivity : ComponentActivity() {
+
+ private val viewModel: MainViewModel by viewModel()
+
+ @OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContent {
+
+ SplitBusTheme {
+
+ val backStack = remember { mutableStateListOf(HomeScreenKey) }
+
+ val barsVisible = TOP_LEVEL_ROUTES.map { it.navKey }.contains(backStack.last())
+
+ val busStopFavourites = viewModel.busStopFavourites
+
+ val busLinesFavourites = viewModel.busLinesFavourites
+
+ Scaffold(
+ bottomBar = {
+ if (barsVisible) {
+ NavigationBar {
+ TOP_LEVEL_ROUTES.forEach { topLevelRoute ->
+
+ val isSelected = topLevelRoute.navKey == backStack.last()
+
+ NavigationBarItem(
+ selected = isSelected,
+ onClick = {
+ backStack.add(topLevelRoute.navKey)
+ if (backStack.size > 2) {
+ backStack.removeAt(1)
+ }
+ },
+ icon = {
+ Icon(
+ imageVector = topLevelRoute.icon,
+ contentDescription = null
+ )
+ }
+ )
+ }
+ }
+ }
+ }
+ ) { innerPadding ->
+ NavDisplay(
+ modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
+ entryDecorators = listOf(
+ rememberSaveableStateHolderNavEntryDecorator(),
+ rememberViewModelStoreNavEntryDecorator()
+ ),
+ backStack = backStack,
+ onBack = { backStack.removeLastOrNull() },
+ entryProvider = entryProvider {
+ entry {
+ HomeScreen(
+ busStopFavourites = busStopFavourites,
+ busLinesFavourites = busLinesFavourites,
+ onBusStopClicked = { busStop ->
+ backStack.add(BusStopArrivalsDetailScreenKey(busStop))
+ },
+ onBusLineClicked = { busLine ->
+ backStack.add(TimetableDetailScreenKey(busLine))
+ }
+ )
+ }
+ entry {
+ BusStopArrivalsListScreen {
+ backStack.add(BusStopArrivalsDetailScreenKey(it))
+ }
+ }
+ entry {
+ val favourite = busStopFavourites.contains(it.busStop)
+ BusStopArrivalsDetailScreen(
+ busStop = it.busStop,
+ favourite = favourite,
+ onFavouriteClicked = { busStop ->
+ if (favourite) {
+ viewModel.removeBusStopFromFavourites(busStop)
+ } else {
+ viewModel.addBusStopToFavourites(busStop)
+ }
+ },
+ onBackClicked = {
+ backStack.removeAt(backStack.lastIndex)
+ }
+ )
+ }
+ entry {
+ TimetablesScreen {
+ backStack.add(TimetableDetailScreenKey(it))
+ }
+ }
+ entry {
+ val favourite = busLinesFavourites.contains(it.busLine)
+ TimetablesDetailScreen(
+ busLine = it.busLine,
+ favourite = favourite,
+ onFavouriteClicked = { busLine ->
+ if (favourite) {
+ viewModel.removeBusLineFromFavourites(busLine)
+ } else {
+ viewModel.addBusLineToFavourites(busLine)
+ }
+ },
+ onBackClicked = {
+ backStack.removeAt(backStack.lastIndex)
+ }
+ )
+ }
+ }
+ )
+ }
+ }
+ }
+ }
+}
+
+// Bottom Bar
+private sealed interface BottomBarRoutes {
+ val icon: ImageVector
+ val navKey: NavKey
+}
+
+private data object Home : BottomBarRoutes {
+ override val icon = Icons.Default.Home
+ override val navKey: NavKey = HomeScreenKey
+}
+
+private data object BusStops : BottomBarRoutes {
+ override val icon = Icons.Rounded.DepartureBoard
+ override val navKey: NavKey = BusStopsScreenKey
+}
+
+private data object TimetablesList : BottomBarRoutes {
+ override val icon = Icons.Default.DirectionsBus
+ override val navKey: NavKey = TimetablesListScreenKey
+}
+
+private val TOP_LEVEL_ROUTES: List =
+ listOf(Home, BusStops, TimetablesList)
+
+
+@Serializable
+data object HomeScreenKey : NavKey
+
+@Serializable
+data object BusStopsScreenKey : NavKey
+
+@Serializable
+data object TimetablesListScreenKey : NavKey
+
+@Serializable
+data class TimetableDetailScreenKey(val busLine: BusLine) : NavKey
+
+@Serializable
+data class BusStopArrivalsDetailScreenKey(val busStop: BusStop) : NavKey
diff --git a/app/src/main/java/com/am/stbus/presentation/MainViewModel.kt b/app/src/main/java/com/am/stbus/presentation/MainViewModel.kt
new file mode 100644
index 0000000..0951bf1
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/MainViewModel.kt
@@ -0,0 +1,96 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.presentation
+
+import androidx.compose.runtime.mutableStateListOf
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.am.stbus.data.models.BusLine
+import com.am.stbus.data.models.BusStop
+import com.am.stbus.data.static.findBusLinePerId
+import com.am.stbus.data.static.findBusStopArrivalPerId
+import com.am.stbus.domain.usecases.FavouritesRoomDbUseCase
+import kotlinx.coroutines.launch
+
+class MainViewModel(
+ private val favouritesRoomDbUseCase: FavouritesRoomDbUseCase
+) : ViewModel() {
+
+ val busStopFavourites =
+ mutableStateListOf()
+
+ val busLinesFavourites =
+ mutableStateListOf()
+
+ init {
+ getAllFavourites()
+ }
+
+ fun getAllFavourites() {
+ viewModelScope.launch {
+ val favourites = favouritesRoomDbUseCase.getAllTimetable()
+
+ val busStops =
+ favourites.filter { it.type == 0 }.mapNotNull { findBusStopArrivalPerId(it.id) }
+ val busLines = favourites.filter { it.type == 1 }.mapNotNull { findBusLinePerId(it.id) }
+
+ busStopFavourites.addAll(busStops)
+ busLinesFavourites.addAll(busLines)
+ }
+ }
+
+ fun addBusStopToFavourites(busStop: BusStop) {
+ viewModelScope.launch {
+ favouritesRoomDbUseCase.add(busStop.id, 0)
+ }
+
+ busStopFavourites.add(busStop)
+ }
+
+ fun removeBusStopFromFavourites(busStop: BusStop) {
+ viewModelScope.launch {
+ favouritesRoomDbUseCase.remove(busStop.id, 0)
+ }
+
+ busStopFavourites.remove(busStop)
+ }
+
+ fun addBusLineToFavourites(busLine: BusLine) {
+ viewModelScope.launch {
+ favouritesRoomDbUseCase.add(busLine.id, 1)
+ }
+
+ busLinesFavourites.add(busLine)
+ }
+
+ fun removeBusLineFromFavourites(busLine: BusLine) {
+ viewModelScope.launch {
+ favouritesRoomDbUseCase.remove(busLine.id, 1)
+ }
+
+ busLinesFavourites.remove(busLine)
+ }
+
+}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/MainActivity.kt b/app/src/main/java/com/am/stbus/presentation/screens/MainActivity.kt
deleted file mode 100644
index d50d7ab..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/MainActivity.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens
-
-import android.os.Build
-import android.os.Bundle
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.appcompat.app.AppCompatDelegate
-import androidx.core.content.ContextCompat
-import androidx.core.view.isVisible
-import androidx.navigation.NavController
-import androidx.navigation.fragment.NavHostFragment
-import androidx.navigation.ui.NavigationUI
-import androidx.preference.PreferenceManager
-import com.am.stbus.R
-import com.am.stbus.common.extensions.changeStatusBarColor
-import kotlinx.android.synthetic.main.activity_main.*
-
-
-class MainActivity : AppCompatActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- setupAppTheme()
-
- //container.systemUiVisibilityFullScreen()
-
- val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
- val navigationController = navHostFragment.navController
-
- // Za skrivanje bottomNavBara
- navigationController.addOnDestinationChangedListener(onDestinationChangedListener)
-
- // This is extremely cool, link bottomNavigationBar with Navigation Controller
- // Because we link them there's no need for BottomNavigationView.onNavigationItemSelectedListener
- // NOTE: id's must same inside nav_graph.xml and bottom_nav_menu.xml
- NavigationUI.setupWithNavController(nav_view, navigationController)
- }
-
- override fun onSupportNavigateUp(): Boolean {
- onBackPressed()
- return true
- }
-
- private val onDestinationChangedListener = NavController.OnDestinationChangedListener { controller, destination, arguments ->
- if (destination.id in ROOT_FRAGMENTS) {
- nav_view.visibility = View.VISIBLE
- supportActionBar?.setDisplayHomeAsUpEnabled(false)
- supportActionBar?.setDisplayShowHomeEnabled(false)
- setupWhiteNavigationNavigationBarColor(true)
- } else {
- nav_view.visibility = View.GONE
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
- supportActionBar?.setDisplayShowHomeEnabled(true)
- setupWhiteNavigationNavigationBarColor(false)
- }
-
- if (destination.id == R.id.informationGmapsFragment) {
- container.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
- this.changeStatusBarColor(R.color.poluprozirniStatusBar)
- } else {
- container.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- this.changeStatusBarColor(R.color.colorPrimaryDark)
- }
-
- app_bar.isVisible = destination.id == R.id.settingsFragment
- }
-
- private fun setupWhiteNavigationNavigationBarColor(white: Boolean) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
- window.navigationBarColor = ContextCompat.getColor(this, R.color.crna)
- }
- else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
- if (white) {
- window.navigationBarColor = ContextCompat.getColor(this, R.color.colorSystemNavigationBackground)
- } else {
- window.navigationBarColor = ContextCompat.getColor(this, R.color.prozirnaAndroid)
- }
- }
-
- }
-
- fun setupAppTheme() {
- val preference = PreferenceManager.getDefaultSharedPreferences(this)
- when (preference.getString("darkMode", "1")) {
- "1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
- "2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- "3" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
- }
- }
-
- companion object {
-
- val ROOT_FRAGMENTS = intArrayOf(
- R.id.favouriteFragment,
- R.id.timetablesFragment,
- R.id.informationListFragment,
- R.id.settingsFragment
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/common/AppBarScreen.kt b/app/src/main/java/com/am/stbus/presentation/screens/common/AppBarScreen.kt
new file mode 100644
index 0000000..90346ef
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/screens/common/AppBarScreen.kt
@@ -0,0 +1,87 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.presentation.screens.common
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextOverflow
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun AppBarScreen(
+ modifier: Modifier = Modifier,
+ title: String,
+ titleColour: Color,
+ showBackButton: Boolean = false,
+ onBackClicked: () -> Unit = {},
+ actions: @Composable RowScope.() -> Unit = {},
+ content: @Composable ColumnScope.() -> Unit = {}
+) {
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .background(MaterialTheme.colorScheme.background)
+ ) {
+ TopAppBar(
+ title = {
+ Text(
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ fontWeight = FontWeight.Bold,
+ color = titleColour,
+ text = title
+ )
+ },
+ actions = actions,
+ navigationIcon = {
+ if (showBackButton) {
+ IconButton(onClick = { onBackClicked() }) {
+ Icon(
+ imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ contentDescription = "Back",
+ tint = titleColour
+ )
+ }
+ }
+ }
+ )
+ content()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/common/ErrorScreen.kt b/app/src/main/java/com/am/stbus/presentation/screens/common/ErrorScreen.kt
new file mode 100644
index 0000000..390e618
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/screens/common/ErrorScreen.kt
@@ -0,0 +1,123 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.presentation.screens.common
+
+import android.content.Intent
+import android.net.Uri
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.core.net.toUri
+import com.am.stbus.R
+import com.am.stbus.common.Constants.PROMET_URL
+import com.am.stbus.presentation.theme.SplitBusTheme
+
+@Composable
+fun ErrorScreen(
+ linija: String
+) {
+
+ val context = LocalContext.current
+
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp),
+ verticalArrangement = Arrangement.Center
+ ) {
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ style = MaterialTheme.typography.headlineMedium,
+ text = stringResource(R.string.snippet_error_title),
+ textAlign = TextAlign.Center
+ )
+ Spacer(modifier = Modifier.height(12.dp))
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ text = stringResource(R.string.snippet_error_desc),
+ textAlign = TextAlign.Center
+ )
+ Spacer(modifier = Modifier.height(12.dp))
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.Center
+ ) {
+ OutlinedButton(
+ onClick = {
+ context.startActivity(
+ Intent.createChooser(
+ Intent(
+ Intent.ACTION_SENDTO,
+ Uri.fromParts("mailto", "antoniomarinnn@gmail.com", null)
+ ).apply {
+ putExtra(Intent.EXTRA_SUBJECT, "Split Bus")
+ putExtra(
+ Intent.EXTRA_TEXT,
+ "Molimo opisite problem!(Please describe your issue!)" +
+ "\n Linija: $linija \n\n"
+ )
+ }, "Email"
+ )
+ )
+ }
+ ) {
+ Text(stringResource(R.string.snippet_error_report))
+ }
+ Spacer(modifier = Modifier.width(12.dp))
+ OutlinedButton(
+ onClick = {
+ context.startActivity(Intent(Intent.ACTION_VIEW, PROMET_URL.toUri()))
+ }
+ ) {
+ Text(stringResource(R.string.snippet_error_promet))
+ }
+ }
+
+ }
+}
+
+@Preview
+@Composable
+fun ErrorScreenPreview() {
+ SplitBusTheme {
+ ErrorScreen("test")
+ }
+}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/common/LoadingScreen.kt b/app/src/main/java/com/am/stbus/presentation/screens/common/LoadingScreen.kt
new file mode 100644
index 0000000..89725b6
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/screens/common/LoadingScreen.kt
@@ -0,0 +1,96 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2013 - 2025 Antonio Marin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.am.stbus.presentation.screens.common
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.CircularWavyProgressIndicator
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.LoadingIndicator
+import androidx.compose.material3.LoadingIndicatorDefaults
+import androidx.compose.material3.MaterialShapes
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.am.stbus.presentation.theme.SplitBusTheme
+
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
+@Composable
+fun LoadingScreen() {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(MaterialTheme.colorScheme.background)
+ ) {
+ LoadingIndicator(
+ modifier = Modifier
+ .scale(4f)
+ .padding(top = 24.dp)
+ .align(Alignment.Center),
+ color = MaterialTheme.colorScheme.secondary,
+ polygons = LoadingIndicatorDefaults.IndeterminateIndicatorPolygons
+ )
+
+ CircularWavyProgressIndicator(
+ modifier = Modifier
+ .scale(7f)
+ .padding(top = 64.dp, start = 8.dp, end = 0.dp)
+ .align(Alignment.CenterEnd),
+ color = MaterialTheme.colorScheme.primary,
+ stroke = Stroke(width = 0.3f),
+ amplitude = 1f
+ )
+
+ LoadingIndicator(
+ modifier = Modifier
+ .scale(2.5f)
+ .padding(end = 64.dp, top = 148.dp)
+ .align(Alignment.Center),
+ color = MaterialTheme.colorScheme.tertiary,
+ polygons = listOf(
+ MaterialShapes.SoftBoom,
+ MaterialShapes.Sunny,
+ MaterialShapes.Gem,
+ MaterialShapes.Pill,
+ MaterialShapes.Clover4Leaf
+ )
+ )
+ }
+}
+
+@Preview
+@Composable
+fun LoadingScreenPreview() {
+ SplitBusTheme {
+ LoadingScreen()
+ }
+}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesAdapter.kt b/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesAdapter.kt
deleted file mode 100644
index 00fe7cc..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesAdapter.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.favourites
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.PopupMenu
-import androidx.appcompat.view.ContextThemeWrapper
-import androidx.recyclerview.widget.RecyclerView
-import com.am.stbus.R
-import com.am.stbus.common.TimetablesData
-import com.am.stbus.domain.models.Timetable
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.TimetablesListFragment.Companion.FAVOURITE_ADDED
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.TimetablesListFragment.Companion.FAVOURITE_REMOVED
-import kotlinx.android.synthetic.main.item_row_timetable.view.*
-
-class FavouritesAdapter(val context: Context?,
- var onClickListener: (Timetable) -> Unit,
- var onClickFavourites: (Int, Timetable) -> Unit,
- var onClickMenuGmaps: (Timetable) -> Unit
-) : RecyclerView.Adapter() {
-
- private var items = mutableListOf()
-
- fun addEntireData(timetables: List) {
- items.addAll(timetables)
- //notifyItemRangeInserted(0, timetables.size)
- // Dodati remove funkcije...
- notifyDataSetChanged()
- }
-
- fun removeFavourite(position: Int) {
- items.removeAt(position)
- notifyItemRemoved(position)
- notifyItemRangeChanged(position, items.size)
- }
-
- fun addItem(news: Timetable) {
- items.add(news)
- }
-
- fun clear() {
- items.clear()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationsViewHolder {
- val itemView = LayoutInflater.from(parent.context)
- .inflate(R.layout.item_row_timetable, parent, false)
- return NotificationsViewHolder(itemView)
- }
-
- override fun getItemCount(): Int {
- return items.size
- }
-
- override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
- holder.bind(position)
- }
-
- inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-
- fun bind(position: Int) {
-
- val item = items[position]
-
- itemView.apply {
- tv_line_id.text = item.lineNumber
- tv_line_name.text = context.getString(TimetablesData().getTimetableTitle(item.lineId))
- setOnClickListener {
- onClickListener(item)
- }
-
- iv_menu.setOnClickListener {
- PopupMenu(ContextThemeWrapper(it.context, R.style.ListPopup), it).apply {
- inflate(R.menu.menu_timetable_list)
-
- // Favourites labels
- menu.findItem(R.id.action_favourites).let { menuItem ->
- when (item.favourite) {
- FAVOURITE_REMOVED -> menuItem.setTitle(R.string.timetables_menu_add_to_favourites)
- FAVOURITE_ADDED -> menuItem.setTitle(R.string.timetables_menu_remove_from_favourites)
- else -> throw IllegalArgumentException("Illegal favourite status ${item.favourite}")
- }
- }
-
- // onClickListeners
- setOnMenuItemClickListener { menuItem ->
- when (menuItem.itemId) {
- R.id.action_favourites -> onClickFavourites(position, item)
- R.id.action_gmaps -> onClickMenuGmaps(item)
- }
- true
- }
- }.show()
- }
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesFragment.kt
deleted file mode 100644
index 67d8336..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesFragment.kt
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.favourites
-
-import android.content.Context
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.fragment.app.Fragment
-import androidx.navigation.findNavController
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.am.stbus.BuildConfig
-import com.am.stbus.R
-import com.am.stbus.domain.models.Timetable
-import com.am.stbus.presentation.screens.settings.ContentFragment.Companion.FIRST_RUN_CONTENT
-import com.am.stbus.presentation.screens.settings.ContentFragment.Companion.UPDATE_APP_CONTENT
-import com.am.stbus.presentation.screens.timetables.TimetablesSharedViewModel
-import kotlinx.android.synthetic.main.fragment_favourites.*
-import org.koin.androidx.navigation.koinNavGraphViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import timber.log.Timber
-
-class FavouritesFragment : Fragment() {
-
- private val timetablesSharedViewModel: TimetablesSharedViewModel by koinNavGraphViewModel(R.id.nav_graph)
-
- private val viewModel: FavouritesViewModel by viewModel()
-
- private val favouriteAdapter by lazy {
- FavouritesAdapter(
- requireContext(),
- { onTimetableClicked(it) },
- { position, timetable -> onTimetableFavouritesClicked(position, timetable) },
- { onTimetableGmapsClicked(it) }
- )
- }
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_favourites, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.title = getString(R.string.nav_favourites)
-
- rv_timetables.apply {
- layoutManager = LinearLayoutManager(requireContext())
- setHasFixedSize(false)
- adapter = favouriteAdapter
- }
-
- timetablesSharedViewModel.timetables.observe(viewLifecycleOwner) { timetables ->
- val favouriteTimetables = timetables?.filter { it.favourite == 1 } ?: emptyList()
- populateFavouriteTimetables(favouriteTimetables)
- }
-
- viewModel.timetableList.observe(viewLifecycleOwner) { timetablesEvent ->
- timetablesEvent.getContentIfNotHandled {
- populateFavouriteTimetables(it)
- }
- }
-
- viewModel.removedFavourite.observe(viewLifecycleOwner) {
- timetablesSharedViewModel.updateFavourite(it.lineId, it.favourite)
- }
-
- checkShouldWelcomeBeShown()
- }
-
- private fun populateFavouriteTimetables(timetables: List) {
-
- favouriteAdapter.clear()
- favouriteAdapter.addEntireData(timetables)
-
- rv_timetables.isVisible = timetables.isNotEmpty()
- tv_empty_title.isVisible = timetables.isEmpty()
- tv_empty_message.isVisible = timetables.isEmpty()
-
-
- }
-
- private fun checkShouldWelcomeBeShown() {
- val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
-
- when (sharedPref.getInt(
- SHARED_PREFS_BUILD_VERSION_KEY,
- SHARED_PREFS_BUILD_VERSION_DEFAULT_VALUE
- )) {
- BuildConfig.VERSION_CODE -> Timber.i("All good! :)")
- SHARED_PREFS_BUILD_VERSION_DEFAULT_VALUE -> showWelcomeFragment(FIRST_RUN_CONTENT)
- else -> showWelcomeFragment(UPDATE_APP_CONTENT)
- }
- }
-
- private fun showWelcomeFragment(updateAppContent: Int) {
-
- // Pokreni Welcome fragment
- requireView().findNavController().navigate(
- FavouritesFragmentDirections.actionFavouriteFragmentToContentFragment(
- when (updateAppContent) {
- FIRST_RUN_CONTENT -> FIRST_RUN_CONTENT
- UPDATE_APP_CONTENT -> UPDATE_APP_CONTENT
- else -> throw IllegalArgumentException("Wrong first run argument")
- }
- )
- )
-
- // Update value in shared prefs
- val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
- with(sharedPref.edit()) {
- putInt(SHARED_PREFS_BUILD_VERSION_KEY, BuildConfig.VERSION_CODE)
- commit()
- }
-
- }
-
- private fun onTimetableClicked(timetable: Timetable) {
- requireView().findNavController().navigate(
- FavouritesFragmentDirections
- .actionFavouriteFragmentToTimetableDetailFragment(
- timetable.lineId,
- timetable.lineNumber,
- timetable.gmapsId,
- timetable.areaId,
- timetable.favourite,
- timetable.content,
- timetable.contentDate
- )
- )
- }
-
- private fun onTimetableFavouritesClicked(position: Int, timetable: Timetable) {
- viewModel.removeFavouritesStatus(position, timetable)
- }
-
- private fun onTimetableGmapsClicked(timetable: Timetable) {
- requireView().findNavController().navigate(
- FavouritesFragmentDirections
- .actionFavouriteFragmentToInformationGmapsFragment(timetable.gmapsId)
- )
- }
-
- companion object {
- const val SHARED_PREFS_SPLIT_BUS = "SB_PREFERENCES"
- const val SHARED_PREFS_BUILD_VERSION_KEY = "BUILD_VERSION"
- const val SHARED_PREFS_BUILD_VERSION_DEFAULT_VALUE = 0
- }
-
-}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesViewModel.kt b/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesViewModel.kt
deleted file mode 100644
index b7ffede..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/favourites/FavouritesViewModel.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.favourites
-
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import com.am.stbus.common.TimetablesData
-import com.am.stbus.common.helpers.Event
-import com.am.stbus.common.helpers.inEvent
-import com.am.stbus.domain.models.Timetable
-import com.am.stbus.domain.usecases.timetables.TimetableListUseCase
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.TimetablesListFragment
-import com.am.stbus.presentation.screens.timetables.timetablesListFragment.TimetablesListFragment.Companion.FAVOURITE_REMOVED
-import io.reactivex.CompletableObserver
-import io.reactivex.SingleObserver
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.disposables.Disposable
-import io.reactivex.schedulers.Schedulers
-
-class FavouritesViewModel(private val timetableListUseCase: TimetableListUseCase) : ViewModel() {
-
- private val schedulers = Schedulers.io()
- private val thread = AndroidSchedulers.mainThread()
-
- private val _timetableList = MutableLiveData>>()
- val timetableList: LiveData>>
- get() = _timetableList
-
- private val _removedFavourite = MutableLiveData()
- val removedFavourite: LiveData
- get() = _removedFavourite
-
- init {
- getTimetables()
- }
-
- private fun getTimetables() {
- timetableListUseCase.getTimetables()
- .subscribeOn(schedulers)
- .observeOn(thread)
- .subscribe(object : SingleObserver> {
- override fun onSuccess(timetables: List) {
- if (timetables.isEmpty()) {
- saveTimetables()
- } else {
- val favouriteTimetables = timetables.filter { it.favourite == 1 }
- _timetableList.postValue(favouriteTimetables.inEvent())
- }
- }
-
- override fun onSubscribe(d: Disposable) {
- // TODO
- }
-
- override fun onError(e: Throwable) {
- // TODO
- }
-
- })
- }
-
- private fun saveTimetables() {
- timetableListUseCase.saveTimetables(TimetablesData.list)
- .subscribeOn(schedulers)
- .observeOn(thread)
- .subscribe(object : CompletableObserver {
- override fun onComplete() {
- _timetableList.postValue(emptyList().inEvent())
- }
-
- override fun onSubscribe(d: Disposable) {
- }
-
- override fun onError(e: Throwable) {
- }
- })
- }
-
- fun removeFavouritesStatus(position: Int, timetable: Timetable) {
- timetableListUseCase.updateFavourites(timetable.lineId, FAVOURITE_REMOVED)
- .subscribeOn(schedulers)
- .observeOn(thread)
- .subscribe(object : CompletableObserver {
- override fun onComplete() {
- _removedFavourite.postValue(
- TimetablesListFragment.UpdatedFavourite(
- position,
- timetable.lineId,
- FAVOURITE_REMOVED
- )
- )
- }
-
- override fun onSubscribe(d: Disposable) {
- }
-
- override fun onError(e: Throwable) {
- }
- })
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/home/HomeScreen.kt b/app/src/main/java/com/am/stbus/presentation/screens/home/HomeScreen.kt
new file mode 100644
index 0000000..5c82db1
--- /dev/null
+++ b/app/src/main/java/com/am/stbus/presentation/screens/home/HomeScreen.kt
@@ -0,0 +1,129 @@
+package com.am.stbus.presentation.screens.home
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.BusAlert
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.am.stbus.R
+import com.am.stbus.data.models.BusLine
+import com.am.stbus.data.models.BusStop
+import com.am.stbus.presentation.screens.common.AppBarScreen
+import com.am.stbus.presentation.screens.stops.list.BusStopItemView
+import com.am.stbus.presentation.screens.timetables.list.BusLineItemView
+import com.am.stbus.presentation.theme.SplitBusTheme
+
+@Composable
+fun HomeScreen(
+ busStopFavourites: List,
+ busLinesFavourites: List,
+ onBusStopClicked: (BusStop) -> Unit,
+ onBusLineClicked: (BusLine) -> Unit
+) {
+
+ val emptyScreen = busStopFavourites.isEmpty() && busLinesFavourites.isEmpty()
+
+ AppBarScreen(
+ title = stringResource(R.string.nav_favourites),
+ titleColour = MaterialTheme.colorScheme.primary
+ ) {
+ if (emptyScreen) {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Icon(
+ modifier = Modifier.size(52.dp),
+ imageVector = Icons.Rounded.BusAlert,
+ contentDescription = "Back",
+ tint = MaterialTheme.colorScheme.primary,
+ )
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 16.dp, start = 16.dp, end = 16.dp),
+ style = MaterialTheme.typography.headlineSmall,
+ textAlign = TextAlign.Center,
+ text = stringResource(id = R.string.favourite_empty_title)
+ )
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 8.dp, start = 16.dp, end = 16.dp),
+ textAlign = TextAlign.Center,
+ text = stringResource(id = R.string.favourite_empty_message)
+ )
+ }
+ } else {
+ if (busStopFavourites.isNotEmpty()) {
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp, vertical = 8.dp),
+ text = stringResource(R.string.nav_bus_stops),
+ fontSize = 18.sp,
+ fontWeight = FontWeight.SemiBold,
+ color = MaterialTheme.colorScheme.tertiary
+ )
+ busStopFavourites.forEach { busStop ->
+ BusStopItemView(
+ busStop = busStop,
+ onBusStopClicked = onBusStopClicked
+ )
+ }
+ }
+ if (busLinesFavourites.isNotEmpty()) {
+ Spacer(modifier = Modifier.height(12.dp))
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp, vertical = 8.dp),
+ text = stringResource(R.string.nav_timetables),
+ fontSize = 18.sp,
+ fontWeight = FontWeight.SemiBold,
+ color = MaterialTheme.colorScheme.secondary
+ )
+ busLinesFavourites.forEach {
+ BusLineItemView(
+ busLine = it,
+ onBusLineClicked = onBusLineClicked
+ )
+ }
+ }
+ }
+ }
+
+}
+
+@Preview
+@Composable
+fun HomeScreenPreview() {
+ SplitBusTheme {
+ Row(
+ modifier = Modifier
+ .fillMaxSize()
+ ) {
+ HomeScreen(emptyList(), emptyList(), {}) { }
+ //omeScreen()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListAdapter.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListAdapter.kt
deleted file mode 100644
index 6ed44cd..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListAdapter.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.recyclerview.widget.RecyclerView
-import com.am.stbus.R
-import com.am.stbus.common.InformationConstants.TYPE_HEADER
-import com.am.stbus.common.InformationConstants.TYPE_ITEM
-import com.am.stbus.domain.models.Information
-import kotlinx.android.synthetic.main.item_row_information_header.view.*
-import kotlinx.android.synthetic.main.item_row_information_item.view.*
-
-
-class InformationListAdapter(val context: Context?,
- var onClickListener: (Information) -> Unit
-) : RecyclerView.Adapter() {
-
- private var informationList = mutableListOf()
- private val positionsThatShouldHideDivider: List = listOf(1, 6, 11)
-
- fun addEntireData(notificationsData: List) {
- informationList.addAll(notificationsData)
- notifyDataSetChanged()
- }
-
- fun addItem(information: Information) {
- informationList.add(information)
- }
-
- fun clear() {
- informationList.clear()
- }
-
- fun isEmpty(): Boolean {
- return informationList.isEmpty()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- return when(viewType) {
- TYPE_HEADER -> HeaderViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_row_information_header, parent, false))
- TYPE_ITEM -> ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_row_information_item, parent, false))
- else -> throw IllegalArgumentException("Wrong type")
- }
- }
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- when (holder) {
- is ItemViewHolder -> {
- holder.bind(position)
- }
- is HeaderViewHolder -> {
- holder.bind(position)
- }
- }
-
- }
-
- override fun getItemViewType(position: Int): Int {
- return informationList[position].viewType
- }
-
- override fun getItemCount(): Int {
- return informationList.size
- }
-
-
- inner class HeaderViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
-
- fun bind(position: Int) {
-
- val information = informationList[position]
-
- itemView.apply {
- tv_category.text = information.informationTitle
- }
- }
- }
-
- inner class ItemViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
-
- fun bind(position: Int) {
-
- val information = informationList[position]
-
- itemView.apply {
- tv_title.text = information.informationTitle
- tv_desc.text = information.informationDesc
-
- view.isVisible = !positionsThatShouldHideDivider.contains(position)
-
- setOnClickListener {
- onClickListener(information)
- }
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListFragment.kt
deleted file mode 100644
index 408e3d4..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/InformationListFragment.kt
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information
-
-import android.content.Intent
-import android.content.SharedPreferences
-import android.net.Uri
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Toast
-import androidx.browser.customtabs.CustomTabsIntent
-import androidx.core.content.ContextCompat
-import androidx.fragment.app.Fragment
-import androidx.navigation.Navigation
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.am.stbus.R
-import com.am.stbus.common.Constants.PROMET_URL
-import com.am.stbus.common.InformationConstants.GARAZE_URL
-import com.am.stbus.common.InformationConstants.ID_CYCLES
-import com.am.stbus.common.InformationConstants.ID_GARAGES
-import com.am.stbus.common.InformationConstants.ID_GENERAL_CATEGORY
-import com.am.stbus.common.InformationConstants.ID_GMAPS
-import com.am.stbus.common.InformationConstants.ID_LATEST_NEWS
-import com.am.stbus.common.InformationConstants.ID_MAPS_CATEGORY
-import com.am.stbus.common.InformationConstants.ID_PARKING
-import com.am.stbus.common.InformationConstants.ID_PROMET_WEB
-import com.am.stbus.common.InformationConstants.ID_SUBURBAN_MAP
-import com.am.stbus.common.InformationConstants.ID_TARIFF_ZONES_MAP
-import com.am.stbus.common.InformationConstants.ID_TOURIST_INFO
-import com.am.stbus.common.InformationConstants.ID_URBAN_MAP
-import com.am.stbus.common.InformationConstants.ID_WEBSITES_CATEGORY
-import com.am.stbus.common.InformationConstants.KARTA_GRAD_URL
-import com.am.stbus.common.InformationConstants.KARTA_PRIGRAD_URL
-import com.am.stbus.common.InformationConstants.NEXT_BIKE_URL
-import com.am.stbus.common.InformationConstants.PARKING_URL
-import com.am.stbus.common.InformationConstants.TARIFNE_URL
-import com.am.stbus.common.InformationConstants.TYPE_HEADER
-import com.am.stbus.common.InformationConstants.TYPE_ITEM
-import com.am.stbus.domain.models.Information
-import kotlinx.android.synthetic.main.fragment_information_list.*
-import org.koin.android.ext.android.inject
-
-class InformationListFragment : Fragment() {
-
- private val preferencesManager: SharedPreferences by inject()
-
- private val informationListAdapter by lazy {
- InformationListAdapter(requireContext()) { onInformationClicked(it) }
- }
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_information_list, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.title = getString(R.string.nav_information)
-
- recyclerView.apply {
- layoutManager = LinearLayoutManager(requireContext())
- setHasFixedSize(true)
- adapter = informationListAdapter
- }
-
- if (informationListAdapter.isEmpty()) {
- informationListAdapter.addEntireData(generateInformationList())
- }
- }
-
- private fun onInformationClicked(information: Information) {
- when (information.informationId) {
- ID_LATEST_NEWS -> navigateToFragment(information)
- ID_TOURIST_INFO -> Toast.makeText(requireContext(), requireContext().getText(R.string.error_still_not_finished), Toast.LENGTH_SHORT).show()
- ID_GMAPS -> navigateToFragment(information)
- ID_URBAN_MAP -> navigateToFragment(information)
- ID_SUBURBAN_MAP -> navigateToFragment(information)
- ID_TARIFF_ZONES_MAP -> navigateToFragment(information)
- ID_CYCLES -> loadUrl(NEXT_BIKE_URL)
- ID_PARKING -> loadUrl(PARKING_URL)
- ID_GARAGES -> loadUrl(GARAZE_URL)
- ID_PROMET_WEB -> loadUrl(PROMET_URL)
- else -> throw IllegalArgumentException("Wrong information destination!")
- }
- }
-
- private fun navigateToFragment(information: Information) {
- Navigation.findNavController(requireView()).navigate(let {
- when (information.informationId) {
- ID_LATEST_NEWS -> InformationListFragmentDirections.actionInformationListFragmentToInformationNewsListFragment()
- //ID_TOURIST_INFO -> Toast.makeText(context, context!!.getText(R.string.error_still_not_finished), Toast.LENGTH_SHORT).show()
- ID_GMAPS -> InformationListFragmentDirections.actionInformationListFragmentToInformationGmapsFragment(0)
- ID_URBAN_MAP -> InformationListFragmentDirections.actionInformationListFragmentToInformationImageViewFragment(getString(R.string.information_urban_map_title), KARTA_GRAD_URL)
- ID_SUBURBAN_MAP -> InformationListFragmentDirections.actionInformationListFragmentToInformationImageViewFragment(getString(R.string.information_suburban_map_title), KARTA_PRIGRAD_URL)
- ID_TARIFF_ZONES_MAP -> InformationListFragmentDirections.actionInformationListFragmentToInformationImageViewFragment(getString(R.string.information_tariff_zones_title), TARIFNE_URL)
- //ID_CYCLES -> InformationListFragmentDirections.actionInformationListFragmentToInformationWebViewFragment(getString(R.string.information_cycles_title), NEXT_BIKE_IFRAME)
- else -> throw IllegalArgumentException("Wrong information destination!")
- }
- })
- }
-
- private fun startGmapsActivity() {
- Toast.makeText(requireContext(), R.string.information_gmaps_not_ready, Toast.LENGTH_SHORT).show()
-// val intent = Intent(context, GmapsActivity::class.java)
-// startActivity(intent)
- }
-
- private fun loadUrl(url: String) {
- if (preferencesManager.getBoolean("open_urls", true)) {
- val customTabsIntent : CustomTabsIntent = buildCustomTabsIntent()
- customTabsIntent.launchUrl(requireContext(), Uri.parse(url))
- } else {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- requireContext().startActivity(intent)
- }
- }
-
- private fun buildCustomTabsIntent(): CustomTabsIntent {
- val intentBuilder = CustomTabsIntent.Builder()
- // Show the title
- intentBuilder.setShowTitle(true)
- // Set the color of Toolbar
- intentBuilder.setToolbarColor(ContextCompat.getColor(requireContext(), R.color.colorPrimary))
- return intentBuilder.build()
- }
-
- private fun generateInformationList(): List {
- return listOf(
- Information(ID_GENERAL_CATEGORY, TYPE_HEADER, getString(R.string.information_news_general_category), ""),
- Information(ID_LATEST_NEWS, TYPE_ITEM, getString(R.string.information_news_title), getString(R.string.information_news_desc)),
- //Information(ID_TOURIST_INFO, TYPE_ITEM, getString(R.string.information_tourist_title), getString(R.string.information_tourist_desc)),
- // Karte
- Information(ID_MAPS_CATEGORY, TYPE_HEADER, getString(R.string.information_news_maps_category), ""),
- Information(ID_GMAPS, TYPE_ITEM, getString(R.string.information_gmaps_title), getString(R.string.information_gmaps_desc)),
- Information(ID_URBAN_MAP, TYPE_ITEM, getString(R.string.information_urban_map_title), getString(R.string.information_urban_map_desc)),
- Information(ID_SUBURBAN_MAP, TYPE_ITEM, getString(R.string.information_suburban_map_title), getString(R.string.information_suburban_map_desc)),
- Information(ID_TARIFF_ZONES_MAP, TYPE_ITEM, getString(R.string.information_tariff_zones_title), getString(R.string.information_tariff_zones_desc)),
- // Ostali web
- Information(ID_WEBSITES_CATEGORY, TYPE_HEADER, getString(R.string.information_websites_category), ""),
- Information(ID_CYCLES, TYPE_ITEM, getString(R.string.information_cycles_title), getString(R.string.information_cycles_desc)),
- Information(ID_PARKING, TYPE_ITEM, getString(R.string.information_parking_title), getString(R.string.information_parking_desc)),
- Information(ID_GARAGES, TYPE_ITEM, getString(R.string.information_garage_title), getString(R.string.information_garage_desc)),
- Information(ID_PROMET_WEB, TYPE_ITEM, getString(R.string.information_promet_web), getString(R.string.information_promet_desc))
- )
- }
-
-}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationGmapsFragment/InformationGmapsFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationGmapsFragment/InformationGmapsFragment.kt
deleted file mode 100644
index 1bb4544..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationGmapsFragment/InformationGmapsFragment.kt
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationGmapsFragment
-
-import android.content.pm.PackageManager
-import android.os.Build
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Toast
-import androidx.appcompat.app.AlertDialog
-import androidx.core.content.ContextCompat
-import androidx.core.content.PermissionChecker
-import androidx.core.content.PermissionChecker.checkSelfPermission
-import androidx.core.view.ViewCompat
-import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.findNavController
-import androidx.navigation.fragment.navArgs
-import androidx.preference.PreferenceManager
-import com.am.stbus.R
-import com.am.stbus.common.extensions.toPx
-import com.am.stbus.presentation.screens.gmaps.data.*
-import com.am.stbus.presentation.screens.gmaps.data.CityRoutesData.GLAVNE_STANICE
-import com.google.android.gms.location.FusedLocationProviderClient
-import com.google.android.gms.location.LocationServices
-import com.google.android.gms.maps.CameraUpdateFactory
-import com.google.android.gms.maps.GoogleMap
-import com.google.android.gms.maps.OnMapReadyCallback
-import com.google.android.gms.maps.SupportMapFragment
-import com.google.android.gms.maps.model.*
-import kotlinx.android.synthetic.main.fragment_information_image_view.*
-
-
-class InformationGmapsFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnInfoWindowClickListener {
-
- private val args: InformationGmapsFragmentArgs by navArgs()
-
- private lateinit var fusedLocationClient: FusedLocationProviderClient
-
- private lateinit var map: GoogleMap
-
- private var leftPadding: Int = 0
- private var topPadding: Int = 0
- private var rightPadding: Int = 0
- private var bottomPadding: Int = 0
-
- private var selectedItems = mutableSetOf()
-
- private var initialPopupShown = false
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
-
- requireActivity().window.apply {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- statusBarColor = ContextCompat.getColor(requireContext(), R.color.poluprozirniStatusBar)
- }
- }
-
- return inflater.inflate(R.layout.fragment_information_gmaps, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.apply {
- setNavigationIcon(R.drawable.ic_arrow_back_black)
- setNavigationOnClickListener {
- findNavController().popBackStack()
- }
- inflateMenu(R.menu.menu_gmaps)
- setOnMenuItemClickListener {
- onOptionsItemSelected(it)
- }
- }
-
- ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
- leftPadding = insets.systemWindowInsetLeft
- topPadding = insets.systemWindowInsetTop + 56.toPx()
- rightPadding = insets.systemWindowInsetRight
- bottomPadding = insets.systemWindowInsetBottom
- insets
- }
-
- val mapFragment: SupportMapFragment = childFragmentManager
- .findFragmentById(R.id.map) as SupportMapFragment
- mapFragment.getMapAsync(this)
- }
-
- override fun onMapReady(googleMap: GoogleMap) {
- map = googleMap
-
- map.apply {
- uiSettings.isZoomControlsEnabled = true
- animateCamera(CameraUpdateFactory.newLatLngZoom(Stanice.VUKKAMPUSS, 12f))
- uiSettings.isMapToolbarEnabled = true
- }
-
- val customInfoWindow = GmapsBusStopInfoView(requireContext())
- map.setInfoWindowAdapter(customInfoWindow)
- map.setPadding(leftPadding, topPadding, rightPadding, bottomPadding)
- map.setOnInfoWindowClickListener(this)
-
-
- val myPreference = PreferenceManager.getDefaultSharedPreferences(requireContext())
- when (myPreference.getString("maptype", "2")) {
- "1" -> map.mapType = GoogleMap.MAP_TYPE_HYBRID
- "2" -> map.mapType = GoogleMap.MAP_TYPE_NORMAL
- "3" -> map.mapType = GoogleMap.MAP_TYPE_TERRAIN
- }
-
- if (myPreference.getBoolean("traffic", false)) {
- map.isTrafficEnabled = true
- }
-
- map.setOnCameraMoveListener {
- val cameraPosition = map.cameraPosition
- if (cameraPosition.zoom == 12f && !initialPopupShown) {
- showRouteDirectionPopup(args.gmapsId)
- initialPopupShown = true
- }
- }
-// googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
-// @Override
-// public void onCameraMove() {
-// CameraPosition cameraPosition = googleMap.getCameraPosition();
-// if(cameraPosition.zoom > 18.0) {
-// googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
-// } else {
-// googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
-// }
-// }
-// });
-
-
- setupUserLocation()
- }
-
- override fun onInfoWindowClick(marker: Marker) {
- createMarkerAlert(marker)
- }
-
-
- private fun setupUserLocation() {
- if (checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PermissionChecker.PERMISSION_GRANTED) {
- requestPermissions(
- arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
- return
- }
-
- // 1
- map.isMyLocationEnabled = true
-
- /* // 2
- fusedLocationClient.lastLocation.addOnSuccessListener(this) { location ->
- // Got last known location. In some rare situations this can be null.
- // 3
- if (location != null) {
- lastLocation = location
- val currentLatLng = LatLng(location.latitude, location.longitude)
- //map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))
- }
- }*/
- }
-
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- when (requestCode) {
- LOCATION_PERMISSION_REQUEST_CODE -> {
- // If request is cancelled, the result arrays are empty.
- if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
- // Dopusteno
- setupUserLocation()
- } else {
- // TODO: Error message
- // Dopustenje odbijeno
- }
- return
- }
-
- // When se koristi za druga dopustenja kojih nemamo zasad
- else -> {
- // Ignoriraj sve ostalo
- }
- }
- }
-
-
- private fun showRouteDirectionPopup(gmapsId: Int) {
- if (gmapsId == 0) {
- showGeneralStops()
- return
- }
-
- // Prvo vidimo jeli ovaj gmapsId treba otvoriti
- // menu izbornik sa opcijama smjera
- val routeDirection = getListContainingRouteDirections(gmapsId)
-
- if (routeDirection.isEmpty()) {
- selectedItems.add(gmapsId)
- displayLine(gmapsId)
- } else {
- android.app.AlertDialog.Builder(requireContext()).apply {
- setTitle(R.string.information_gmaps_route_selector_popup_title)
- setItems(routeDirection.map {
- getString(returnStringForGmapsId(it))
- }.toTypedArray()) { dialog, which ->
- when (which) {
- 0 -> {
- selectedItems.add(routeDirection[0])
- displayLine(routeDirection[0])
- }
- 1 -> {
- selectedItems.add(routeDirection[1])
- displayLine(routeDirection[1])
- }
- }
- }
- }.create().show()
- }
- }
-
- private fun createMarkerAlert(marker: Marker?) {
- val markerTag = marker!!.tag as MarkerData
-
- val gmapsList = markerTag.gmapsIds
- val booleans = BooleanArray(gmapsList.size)
-
- val routesList = ArrayList()
- gmapsList.forEachIndexed { index, item ->
- routesList.add(requireContext().getString(returnStringForGmapsId(item)))
- booleans[index] = selectedItems.contains(item)
- }
-
- val routesListStringArray = routesList.toArray(arrayOfNulls(routesList.size))
-
- AlertDialog.Builder(requireContext()).apply {
- setTitle(R.string.gmaps_select_title)
- setMultiChoiceItems(routesListStringArray, booleans) { _, indexSelected, isChecked ->
- if (isChecked) {
- selectedItems.add(gmapsList[indexSelected])
- showRouteDirectionPopup(gmapsList[indexSelected])
- } else {
- selectedItems.remove(gmapsList[indexSelected])
- clearAndRedrawMap()
- }
- }
- setNegativeButton(R.string.information_gmaps_route_selector_popup_close) { _, _ ->
-
- }
- create().show()
- }
- }
-
- private fun displayLine(gmapsId: Int) {
-
- val listOfStops = getStopForRoute(gmapsId)
-
- if (listOfStops.isEmpty()) {
- Toast.makeText(requireContext(), R.string.nijejos, Toast.LENGTH_LONG).show()
- return
- }
-
- listOfStops.forEach {
- map.addMarker(MarkerOptions().position(it.latLng!!)
- .title(it.title)
- .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_pin))
- )?.tag = MarkerData(null, it.title, it.lineNumbers, it.gmapsIds)
- }
-
- map.addPolyline(PolylineOptions().addAll(listOfStops.map { it.latLng })
- .width(8f)
- .color(ContextCompat.getColor(requireContext(), R.color.zutaGmapsRute))
- .geodesic(true))
- }
-
-
- private fun clearAndRedrawMap() {
- map.clear()
- selectedItems.forEach {
- displayLine(it)
- }
- }
-
- private fun showGeneralStops() {
- GLAVNE_STANICE.forEach {
- map.addMarker(MarkerOptions().position(it.latLng!!)
- .title(it.title)
- .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_pin))
- )?.tag = MarkerData(null, it.title, it.lineNumbers, it.gmapsIds)
- }
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.action_main_markers -> {
- showGeneralStops()
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- class MarkerData(val latLng: LatLng?, val title: String, val lineNumbers: List, val gmapsIds: List)
-
- companion object {
- private const val LOCATION_PERMISSION_REQUEST_CODE = 1
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationImageViewFragment/InformationImageViewFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationImageViewFragment/InformationImageViewFragment.kt
deleted file mode 100644
index ba6f8c1..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationImageViewFragment/InformationImageViewFragment.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationImageViewFragment
-
-import android.graphics.drawable.Drawable
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.findNavController
-import androidx.navigation.fragment.navArgs
-import com.am.stbus.R
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.DataSource
-import com.bumptech.glide.load.engine.GlideException
-import com.bumptech.glide.request.RequestListener
-import com.bumptech.glide.request.target.Target
-import kotlinx.android.synthetic.main.fragment_information_image_view.*
-
-class InformationImageViewFragment : Fragment() {
-
- private val args: InformationImageViewFragmentArgs by navArgs()
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_information_image_view, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.apply {
- title = args.imageTitle
- setNavigationIcon(R.drawable.ic_arrow_back)
- setNavigationOnClickListener {
- findNavController().popBackStack()
- }
- }
-
- Glide.with(requireContext())
- .load(args.imageUrl)
- .listener(object : RequestListener{
- override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean {
- if (isVisible) {
- pb_loading.isVisible = false
- }
- return false
- }
-
- override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
- if (isVisible) {
- pb_loading.isVisible = false
- }
- return false
- }
-
- })
- .into(iv_slika)
- }
-
-}
-
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListAdapter.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListAdapter.kt
deleted file mode 100644
index 26ae76c..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListAdapter.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationNewsListFragment
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.recyclerview.widget.RecyclerView
-import com.am.stbus.R
-import com.am.stbus.domain.models.NewsListItem
-import kotlinx.android.synthetic.main.item_row_news.view.*
-
-class InformationNewsListAdapter(val context: Context?,
- var onClickListener: (NewsListItem) -> Unit
-) : RecyclerView.Adapter() {
-
- private var items = mutableListOf()
-
- fun addEntireData(news: List) {
- items.addAll(news)
- notifyDataSetChanged()
- }
-
- fun addItem(news: NewsListItem) {
- items.add(news)
- }
-
- fun clear() {
- items.clear()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationsViewHolder {
- val itemView = LayoutInflater.from(parent.context)
- .inflate(R.layout.item_row_news, parent, false)
- return NotificationsViewHolder(itemView)
- }
-
- override fun getItemCount(): Int {
- return items.size
- }
-
- override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
- holder.bind(position)
- }
-
- inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-
- fun bind(position: Int) {
-
- val item = items[position]
-
- itemView.apply {
- titleTextView.text = item.title
- dateTextView.text = item.date
- summaryTextView.text = item.desc
- setOnClickListener {
- onClickListener(item)
- }
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListFragment.kt
deleted file mode 100644
index 6e054c8..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListFragment.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationNewsListFragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.Observer
-import androidx.navigation.findNavController
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.am.stbus.R
-import com.am.stbus.common.extensions.loadEmailReport
-import com.am.stbus.common.extensions.loadPrometUrl
-import com.am.stbus.domain.models.NewsListItem
-import kotlinx.android.synthetic.main.fragment_information_news_list.*
-import kotlinx.android.synthetic.main.snippet_error.*
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class InformationNewsListFragment : Fragment() {
-
- private val viewModel: InformationNewsListViewModel by viewModel()
-
- private val informationNewsListAdapter by lazy {
- InformationNewsListAdapter(requireContext()) { onNewsItemClicked(it) }
- }
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_information_news_list, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.apply {
- setNavigationIcon(R.drawable.ic_arrow_back)
- setNavigationOnClickListener {
- findNavController().popBackStack()
- }
- }
-
- viewModel.newsList.observe(viewLifecycleOwner, Observer> {
- onNewsListAdded(it)
- })
-
- viewModel.loading.observe(viewLifecycleOwner, Observer{
- snippet_loading.isVisible = it
- rv_news_list.isVisible = !it
- })
-
- viewModel.error.observe(viewLifecycleOwner, Observer {
- if (informationNewsListAdapter.itemCount == 0) {
- handleErrorScreen(it)
- }
- })
-
- rv_news_list.apply {
- layoutManager = LinearLayoutManager(requireContext())
- setHasFixedSize(true)
- adapter = informationNewsListAdapter
- }
- }
-
- private fun handleErrorScreen(errorMessage: String?) {
- rv_news_list.isVisible = false
- snippet_loading.isVisible = false
- snippet_error.isVisible = true
-
- btn_promet.setOnClickListener {
- requireContext().loadPrometUrl()
- }
-
- btn_error.setOnClickListener {
- requireContext().loadEmailReport("newsList", errorMessage?:"")
- }
-
- }
-
- private fun onNewsListAdded(it: List) {
- informationNewsListAdapter.clear()
- informationNewsListAdapter.addEntireData(it)
- }
-
- private fun onNewsItemClicked(it: NewsListItem) {
- view?.findNavController()?.navigate(InformationNewsListFragmentDirections
- .actionInformationNewsListFragmentToInformationNewsDetailFragment(
- it.title,
- it.date,
- it.url
- ))
- }
-
-}
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListViewModel.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListViewModel.kt
deleted file mode 100644
index 06220f1..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/InformationNewsListViewModel.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationNewsListFragment
-
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import com.am.stbus.domain.models.NewsListItem
-import com.am.stbus.domain.usecases.news.NewsListUseCase
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-
-
-class InformationNewsListViewModel(
- private val getNewsListUseCase: NewsListUseCase
-) : ViewModel() {
-
- private val _newsList = MutableLiveData>()
- val newsList: LiveData>
- get() = _newsList
-
- private val _loading = MutableLiveData()
- val loading: LiveData
- get() = _loading
-
- private val _error = MutableLiveData()
- val error: LiveData
- get() = _error
-
- init {
- getLocalNewsList()
- }
-
- private fun getLocalNewsList() {
- viewModelScope.launch {
- try {
- val newsList = getNewsListUseCase.getLocalNewsList(Dispatchers.IO)
- if (newsList.isNotEmpty()) {
- _newsList.postValue(newsList)
- _loading.postValue(false)
- } else {
- _loading.postValue(true)
- }
- getRemoteNewsList()
- } catch (e: Exception) {
- _loading.postValue(false)
- _error.postValue(e.localizedMessage)
- }
- }
- }
-
- private fun getRemoteNewsList() {
- viewModelScope.launch {
- try {
- val newsList = getNewsListUseCase.getRemoteNewsList( Dispatchers.IO)
- if (newsList.isNotEmpty()) {
- _newsList.postValue(newsList)
- _loading.postValue(false)
- }
- } catch (e: Exception) {
- _loading.postValue(false)
- _error.postValue(e.localizedMessage)
- }
- }
- }
-}
-
diff --git a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/informationNewsDetailFragment/InformationNewsDetailFragment.kt b/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/informationNewsDetailFragment/InformationNewsDetailFragment.kt
deleted file mode 100644
index 2768d66..0000000
--- a/app/src/main/java/com/am/stbus/presentation/screens/information/informationNewsListFragment/informationNewsDetailFragment/InformationNewsDetailFragment.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2013 - 2021 Antonio Marin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.am.stbus.presentation.screens.information.informationNewsListFragment.informationNewsDetailFragment
-
-import android.graphics.Color
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.webkit.WebView
-import android.webkit.WebViewClient
-import androidx.core.content.ContextCompat
-import androidx.core.view.isVisible
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.Observer
-import androidx.navigation.findNavController
-import androidx.navigation.fragment.navArgs
-import com.am.stbus.R
-import com.am.stbus.common.Constants
-import com.am.stbus.common.extensions.loadUrl
-import com.am.stbus.common.extensions.toPx
-import com.am.stbus.domain.models.NewsItem
-import kotlinx.android.synthetic.main.fragment_information_news_detail.*
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import org.koin.core.parameter.parametersOf
-
-class InformationNewsDetailFragment : Fragment() {
-
- private val viewModel: InformationNewsDetailViewModel by viewModel { parametersOf(args.newsUrl) }
-
- private val args: InformationNewsDetailFragmentArgs by navArgs()
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_information_news_detail, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- toolbar.apply {
- setNavigationIcon(R.drawable.ic_arrow_back)
- setNavigationOnClickListener {
- findNavController().popBackStack()
- }
- }
-
- tv_title.text = args.newsTitle
- tv_date.text = args.newsDate
-
- viewModel.newsItem.observe(viewLifecycleOwner, Observer {
- onNewsLoaded(it)
- })
-
- viewModel.error.observe(viewLifecycleOwner, Observer {
- handleErrorScreen(it)
- })
-
- viewModel.loading.observe(viewLifecycleOwner, Observer {
- pb_loading.isVisible = it
- web_view.isVisible = !it
- })
- }
-
- private fun onNewsLoaded(it: NewsItem) {
- web_view.apply {
- setBackgroundColor(Color.TRANSPARENT)
- isHorizontalScrollBarEnabled = false
- loadDataWithBaseURL("file:///android_res/", formatNewsTextForWebView(it.newsItemContent), "text/html", "utf-8", null)
- }
-
- web_view.webViewClient = object : WebViewClient() {
- override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
- requireContext().loadUrl(Constants.PROMET_URL + url.replace("file://", ""))
- return true
- }
- }
-
- }
-
- private fun formatNewsTextForWebView(newsContent: String): String {
- val textColor = "#" + Integer.toHexString(ContextCompat.getColor(requireContext(), R.color.colorText) and 0x00ffffff)
- val textFixedImageTags = newsContent.replace("src=\"/", "src=\"http://www.promet-split.hr/")
- return "\n " +
- "\n" +
- "" +
- "\n" +
- textFixedImageTags + "\n" +
- "