diff --git a/app/build.gradle b/app/build.gradle
index 00a6b60..075282a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -61,6 +61,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+ implementation "androidx.datastore:datastore-preferences:1.0.0"
// Hilt
implementation "com.google.dagger:hilt-android:2.47"
@@ -131,5 +132,5 @@ dependencies {
implementation(platform("com.google.firebase:firebase-bom:32.7.1"))
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
-
+ implementation("com.google.firebase:firebase-messaging-ktx")
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3cb5cfd..9b52dfa 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,10 @@
-
+
+
+
+
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/MyApplication.kt b/app/src/main/java/com/isolaatti/MyApplication.kt
index dac6db3..6ec689a 100644
--- a/app/src/main/java/com/isolaatti/MyApplication.kt
+++ b/app/src/main/java/com/isolaatti/MyApplication.kt
@@ -1,10 +1,16 @@
package com.isolaatti
import android.app.Application
+import android.content.Context
import android.net.ConnectivityManager
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.preferencesDataStore
import com.isolaatti.connectivity.ConnectivityCallbackImpl
import dagger.hilt.android.HiltAndroidApp
+val Context.dataStore: DataStore by preferencesDataStore(name = "settings")
+
@HiltAndroidApp
class MyApplication : Application() {
diff --git a/app/src/main/java/com/isolaatti/home/HomeActivity.kt b/app/src/main/java/com/isolaatti/home/HomeActivity.kt
index 749bdcd..dd593be 100644
--- a/app/src/main/java/com/isolaatti/home/HomeActivity.kt
+++ b/app/src/main/java/com/isolaatti/home/HomeActivity.kt
@@ -1,14 +1,21 @@
package com.isolaatti.home
+import android.Manifest
+import android.content.SharedPreferences
+import android.content.pm.PackageManager
+import android.os.Build
import android.os.Bundle
import android.view.Menu
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
-import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.Observer
+import androidx.core.content.ContextCompat
+import androidx.datastore.preferences.core.edit
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.isolaatti.R
import com.isolaatti.common.IsolaattiBaseActivity
+import com.isolaatti.dataStore
import com.isolaatti.databinding.ActivityHomeBinding
import com.isolaatti.home.presentation.FeedViewModel
@@ -16,6 +23,18 @@ class HomeActivity : IsolaattiBaseActivity() {
private lateinit var viewBinding: ActivityHomeBinding
private val feedViewModel: FeedViewModel by viewModels()
+ private val requestPermissionLauncher = registerForActivityResult(
+ ActivityResultContracts.RequestPermission(),
+ ) { isGranted: Boolean ->
+ if (!isGranted) {
+ MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.push_notifications_dialog_title)
+ .setMessage(R.string.push_notifications_dialog_rejected_message)
+ .show()
+ }
+ }
+
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewBinding = ActivityHomeBinding.inflate(layoutInflater)
@@ -24,6 +43,8 @@ class HomeActivity : IsolaattiBaseActivity() {
viewBinding.bottomNavigation?.setupWithNavController(navHostFragment.navController)
viewBinding.navigationRail?.setupWithNavController(navHostFragment.navController)
+ askNotificationPermission()
+
if(savedInstanceState == null) {
feedViewModel.getFeed(false)
}
@@ -34,7 +55,28 @@ class HomeActivity : IsolaattiBaseActivity() {
return super.onCreateOptionsMenu(menu)
}
- override fun onDestroy() {
- super.onDestroy()
+ private fun askNotificationPermission() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
+ PackageManager.PERMISSION_GRANTED
+ ) {
+
+ } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
+ MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.push_notifications_dialog_title)
+ .setMessage(R.string.push_notifications_dialog_message)
+ .setPositiveButton(R.string.accept) { _, _ ->
+ requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
+ }
+ .setNegativeButton(R.string.no, null)
+ .show()
+ } else {
+ // Directly ask for the permission
+ requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
+ }
+ } else {
+
+ }
}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsApi.kt b/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsApi.kt
new file mode 100644
index 0000000..7c9c1b0
--- /dev/null
+++ b/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsApi.kt
@@ -0,0 +1,10 @@
+package com.isolaatti.home.notifications.data
+
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+interface NotificationsApi {
+ @GET("/api/Notifications/list")
+ fun getNotifications(@Query("after") after: Long?): Call
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsDto.kt b/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsDto.kt
new file mode 100644
index 0000000..62aa82e
--- /dev/null
+++ b/app/src/main/java/com/isolaatti/home/notifications/data/NotificationsDto.kt
@@ -0,0 +1,22 @@
+package com.isolaatti.home.notifications.data
+
+import java.time.ZonedDateTime
+
+data class NotificationsDto(
+ val result: List
+)
+
+data class NotificationDto(
+ val id: Long,
+ val date: ZonedDateTime,
+ val userId: Int,
+ val read: Boolean,
+ val payload: NotificationPayload
+)
+
+data class NotificationPayload(
+ val type: String,
+ val authorId: Int,
+ val authorName: String?,
+ val intentData: String?
+)
diff --git a/app/src/main/java/com/isolaatti/push_notifications/FcmService.kt b/app/src/main/java/com/isolaatti/push_notifications/FcmService.kt
new file mode 100644
index 0000000..5702a40
--- /dev/null
+++ b/app/src/main/java/com/isolaatti/push_notifications/FcmService.kt
@@ -0,0 +1,25 @@
+package com.isolaatti.push_notifications
+
+import android.Manifest
+import android.util.Log
+import androidx.core.content.ContextCompat
+import com.google.firebase.messaging.FirebaseMessagingService
+import dagger.hilt.EntryPoint
+import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class FcmService : FirebaseMessagingService() {
+ companion object {
+ const val LOG_TAG = "FcmService"
+ }
+
+ @Inject
+ lateinit var pushNotificationsApi: PushNotificationsApi
+
+ override fun onNewToken(token: String) {
+
+ pushNotificationsApi.registerDevice(token)
+ Log.d(LOG_TAG, token)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/push_notifications/Module.kt b/app/src/main/java/com/isolaatti/push_notifications/Module.kt
new file mode 100644
index 0000000..253a001
--- /dev/null
+++ b/app/src/main/java/com/isolaatti/push_notifications/Module.kt
@@ -0,0 +1,16 @@
+package com.isolaatti.push_notifications
+
+import com.isolaatti.connectivity.RetrofitClient
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+
+@Module
+@InstallIn(SingletonComponent::class)
+class Module {
+ @Provides
+ fun providePushNotificationsApi(retrofitClient: RetrofitClient): PushNotificationsApi {
+ return retrofitClient.client.create(PushNotificationsApi::class.java)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/isolaatti/push_notifications/PushNotificationsApi.kt b/app/src/main/java/com/isolaatti/push_notifications/PushNotificationsApi.kt
new file mode 100644
index 0000000..26e2430
--- /dev/null
+++ b/app/src/main/java/com/isolaatti/push_notifications/PushNotificationsApi.kt
@@ -0,0 +1,14 @@
+package com.isolaatti.push_notifications
+
+import retrofit2.Call
+import retrofit2.http.Multipart
+import retrofit2.http.PUT
+import retrofit2.http.Part
+
+interface PushNotificationsApi {
+
+ @PUT("/api/push_notifications/register_device")
+ @Multipart
+ fun registerDevice(@Part("token") token: String): Call
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_push_notifications.xml b/app/src/main/res/layout/dialog_push_notifications.xml
new file mode 100644
index 0000000..77d9ef6
--- /dev/null
+++ b/app/src/main/res/layout/dialog_push_notifications.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d5d7b73..f1a75a8 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -186,4 +186,7 @@
Select audio
Do you really want to remove this audio? Discussions with this audio linked will still be pointing to it.
Remove audio?
+ Push notifications
+ Receive notifications to stay informed about your profile activity
+ You won\'t receive notifications. You can change this on your device settings.
\ No newline at end of file