Initial import of f7cloud-mobile native Android app.

Kotlin/Compose client for F7cloud (mail, files, talk, calendar, contacts, tasks, support).
Current version: 0.5.113 (build 121).
This commit is contained in:
F7cloud Mobile
2026-07-07 12:05:18 +03:00
commit fd17df80a8
1789 changed files with 246889 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- F7cloud embed: strip Talk standalone launcher; host app is F7cloud Mobile. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity
android:name="ru.f7cloud.talk.activities.MainActivity"
tools:node="remove" />
</application>
</manifest>
@@ -0,0 +1,63 @@
/*
* F7cloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package ru.f7cloud.talk.jobs
import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import autodagger.AutoInjector
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.messaging.FirebaseMessaging
import ru.f7cloud.talk.application.F7cloudTalkApplication
import ru.f7cloud.talk.utils.preferences.AppPreferences
import javax.inject.Inject
@AutoInjector(F7cloudTalkApplication::class)
class GetFirebasePushTokenWorker(val context: Context, workerParameters: WorkerParameters) :
Worker(context, workerParameters) {
@Inject
lateinit var appPreferences: AppPreferences
@SuppressLint("LongLogTag")
override fun doWork(): Result {
F7cloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
FirebaseMessaging.getInstance().token.addOnCompleteListener(
OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@OnCompleteListener
}
val pushToken = task.result
Log.d(TAG, "Fetched firebase push token is: $pushToken")
appPreferences.pushToken = pushToken
appPreferences.pushTokenLatestFetch = System.currentTimeMillis()
val data: Data =
Data.Builder().putString(PushRegistrationWorker.ORIGIN, "GetFirebasePushTokenWorker").build()
val pushRegistrationWork = OneTimeWorkRequest.Builder(PushRegistrationWorker::class.java)
.setInputData(data)
.build()
WorkManager.getInstance(context).enqueue(pushRegistrationWork)
}
)
return Result.success()
}
companion object {
private val TAG = GetFirebasePushTokenWorker::class.simpleName
}
}
@@ -0,0 +1,81 @@
/*
* F7cloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2022 Tim Krüger <t@timkrueger.me>
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package ru.f7cloud.talk.services.firebase
import android.util.Log
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import autodagger.AutoInjector
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import ru.f7cloud.talk.application.F7cloudTalkApplication
import ru.f7cloud.talk.application.F7cloudTalkApplication.Companion.sharedApplication
import ru.f7cloud.talk.jobs.NotificationWorker
import ru.f7cloud.talk.jobs.PushRegistrationWorker
import ru.f7cloud.talk.utils.bundle.BundleKeys
import ru.f7cloud.talk.utils.preferences.AppPreferences
import javax.inject.Inject
@AutoInjector(F7cloudTalkApplication::class)
class NCFirebaseMessagingService : FirebaseMessagingService() {
@Inject
lateinit var appPreferences: AppPreferences
override fun onCreate() {
Log.d(TAG, "onCreate")
super.onCreate()
sharedApplication!!.componentApplication.inject(this)
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d(TAG, "onMessageReceived")
sharedApplication!!.componentApplication.inject(this)
Log.d(TAG, "remoteMessage.priority: " + remoteMessage.priority)
Log.d(TAG, "remoteMessage.originalPriority: " + remoteMessage.originalPriority)
val data = remoteMessage.data
val subject = data[KEY_NOTIFICATION_SUBJECT]
val signature = data[KEY_NOTIFICATION_SIGNATURE]
if (!subject.isNullOrEmpty() && !signature.isNullOrEmpty()) {
val messageData = Data.Builder()
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, signature)
.build()
val notificationWork =
OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData)
.build()
WorkManager.getInstance().enqueue(notificationWork)
}
}
override fun onNewToken(token: String) {
super.onNewToken(token)
Log.d(TAG, "onNewToken. token = $token")
appPreferences.pushToken = token
appPreferences.pushTokenLatestGeneration = System.currentTimeMillis()
val data: Data =
Data.Builder().putString(PushRegistrationWorker.ORIGIN, "NCFirebaseMessagingService#onNewToken").build()
val pushRegistrationWork = OneTimeWorkRequest.Builder(PushRegistrationWorker::class.java)
.setInputData(data)
.build()
WorkManager.getInstance().enqueue(pushRegistrationWork)
}
companion object {
private val TAG = NCFirebaseMessagingService::class.simpleName
const val KEY_NOTIFICATION_SUBJECT = "subject"
const val KEY_NOTIFICATION_SIGNATURE = "signature"
}
}
@@ -0,0 +1,93 @@
/*
* F7cloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2022 Andy Scherzinger <info@andy-scherzinger.de>
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package ru.f7cloud.talk.utils
import android.content.Intent
import android.util.Log
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import autodagger.AutoInjector
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.security.ProviderInstaller
import ru.f7cloud.talk.application.F7cloudTalkApplication
import ru.f7cloud.talk.interfaces.ClosedInterface
import ru.f7cloud.talk.jobs.GetFirebasePushTokenWorker
import java.util.concurrent.TimeUnit
@AutoInjector(F7cloudTalkApplication::class)
class ClosedInterfaceImpl :
ClosedInterface,
ProviderInstaller.ProviderInstallListener {
override val isGooglePlayServicesAvailable: Boolean = isGPlayServicesAvailable()
override fun providerInstallerInstallIfNeededAsync() {
F7cloudTalkApplication.sharedApplication?.let {
ProviderInstaller.installIfNeededAsync(
it.applicationContext,
this
)
}
}
override fun onProviderInstalled() {
// unused atm
}
override fun onProviderInstallFailed(p0: Int, p1: Intent?) {
// unused atm
}
private fun isGPlayServicesAvailable(): Boolean {
val api = GoogleApiAvailability.getInstance()
val code =
F7cloudTalkApplication.sharedApplication?.let {
api.isGooglePlayServicesAvailable(it.applicationContext)
}
return if (code == ConnectionResult.SUCCESS) {
true
} else {
Log.w(TAG, "GooglePlayServices are not available. Code:$code")
false
}
}
override fun setUpPushTokenRegistration() {
val firebasePushTokenWorker = OneTimeWorkRequest.Builder(GetFirebasePushTokenWorker::class.java).build()
WorkManager.getInstance().enqueue(firebasePushTokenWorker)
setUpPeriodicTokenRefreshFromFCM()
}
private fun setUpPeriodicTokenRefreshFromFCM() {
val periodicTokenRefreshFromFCM = PeriodicWorkRequest.Builder(
GetFirebasePushTokenWorker::class.java,
DAILY,
TimeUnit.HOURS,
FLEX_INTERVAL,
TimeUnit.HOURS
).build()
WorkManager.getInstance()
.enqueueUniquePeriodicWork(
"periodicTokenRefreshFromFCM",
ExistingPeriodicWorkPolicy.UPDATE,
periodicTokenRefreshFromFCM
)
}
companion object {
private val TAG = ClosedInterfaceImpl::class.java.simpleName
const val DAILY: Long = 24
const val FLEX_INTERVAL: Long = 10
}
}