Commit a41ea261 authored by Romain Hunault's avatar Romain Hunault

Merge branch 'contact_sync_fix' into 'dev'

Issue 26 Fixed

See merge request !15
parents b390d492 a1ec7269
Pipeline #38443 passed with stage
in 5 minutes and 46 seconds
......@@ -34,8 +34,6 @@ android {
versionCode 194
versionName "3.6.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "BUGSNAG_API_KEY", "\"${System.getenv("BUGSNAG_API_KEY")}\""
}
buildTypes {
......@@ -164,7 +162,6 @@ dependencies {
testImplementation "org.mockito:mockito-core:$mockito_version"
implementation "com.android.billingclient:billing:1.0"
implementation "com.bugsnag:bugsnag-android:4.1.1"
implementation "com.github.chrisbanes:PhotoView:2.0.0"
implementation "com.f2prateek.rx.preferences2:rx-preferences:$rx_preferences_version"
implementation "com.google.android:flexbox:0.3.1"
......
......@@ -26,22 +26,14 @@ import androidx.core.provider.FontRequest
import androidx.emoji.text.EmojiCompat
import androidx.emoji.text.FontRequestEmojiCompatConfig
import com.akaita.java.rxjava2debug.RxJava2Debug
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.Configuration
import com.moez.QKSMS.BuildConfig
import com.moez.QKSMS.R
import com.moez.QKSMS.common.util.BugsnagTree
import com.moez.QKSMS.common.util.FileLoggingTree
import com.moez.QKSMS.injection.AppComponentManager
import com.moez.QKSMS.injection.appComponent
import com.moez.QKSMS.manager.AnalyticsManager
import com.moez.QKSMS.migration.QkRealmMigration
import com.moez.QKSMS.util.NightModeManager
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasActivityInjector
import dagger.android.HasBroadcastReceiverInjector
import dagger.android.HasServiceInjector
import dagger.android.*
import io.realm.Realm
import io.realm.RealmConfiguration
import timber.log.Timber
......@@ -58,7 +50,8 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn
@Inject lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
@Inject lateinit var dispatchingBroadcastReceiverInjector: DispatchingAndroidInjector<BroadcastReceiver>
@Inject lateinit var dispatchingServiceInjector: DispatchingAndroidInjector<Service>
@Inject lateinit var fileLoggingTree: FileLoggingTree
@Inject
lateinit var fileLoggingTree: FileLoggingTree
@Inject lateinit var nightModeManager: NightModeManager
private val packages = arrayOf("com.moez.QKSMS")
......@@ -66,11 +59,6 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn
override fun onCreate() {
super.onCreate()
Bugsnag.init(this, Configuration(BuildConfig.BUGSNAG_API_KEY).apply {
appVersion = BuildConfig.VERSION_NAME
projectPackages = packages
})
RxJava2Debug.enableRxJava2AssemblyTracking()
Realm.init(this)
......@@ -88,7 +76,6 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn
}
nightModeManager.updateCurrentTheme()
val fontRequest = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
......@@ -96,8 +83,8 @@ class QKApplication : Application(), HasActivityInjector, HasBroadcastReceiverIn
R.array.com_google_android_gms_fonts_certs)
EmojiCompat.init(FontRequestEmojiCompatConfig(this, fontRequest))
Timber.plant(Timber.DebugTree(), fileLoggingTree)
Timber.plant(Timber.DebugTree(), BugsnagTree(), fileLoggingTree)
}
override fun activityInjector(): AndroidInjector<Activity> {
......
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.common.util
import android.util.Log
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.Severity
import timber.log.Timber
/**
* If an exception is logged with the [Log.WARN] or [Log.ERROR] priority, the exception will be
* sent to Bugsnag
*/
class BugsnagTree : Timber.Tree() {
override fun isLoggable(tag: String?, priority: Int): Boolean {
return priority == Log.WARN || priority == Log.ERROR
}
override fun log(priority: Int, tag: String?, message: String?, throwable: Throwable?) {
val severity = if (priority == Log.ERROR) Severity.ERROR else Severity.WARNING
throwable?.run { Bugsnag.notify(this, severity) }
}
}
\ No newline at end of file
......@@ -18,9 +18,12 @@
*/
package com.moez.QKSMS.feature.gallery
import android.Manifest
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.annotation.NonNull
import androidx.core.app.ActivityCompat
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
......@@ -50,6 +53,7 @@ class GalleryActivity : QkActivity(), GalleryView {
private val optionsItemSubject: Subject<Int> = PublishSubject.create()
private val pageChangedSubject: Subject<MmsPart> = PublishSubject.create()
private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory)[GalleryViewModel::class.java] }
private val permissionResultSubject: Subject<Unit> = PublishSubject.create()
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
......@@ -112,9 +116,28 @@ class GalleryActivity : QkActivity(), GalleryView {
return true
}
override fun onStart() {
super.onStart()
}
override fun onPause() {
super.onPause()
}
override fun onDestroy() {
super.onDestroy()
pagerAdapter.destroy()
}
override fun requestStoragePermission() {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0)
}
override fun onRequestPermissionsResult(requestCode: Int, @NonNull permissions: Array<String>, @NonNull grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
permissionResultSubject.onNext(Unit)
}
override fun permissionResult(): Observable<*> = permissionResultSubject
}
\ No newline at end of file
......@@ -27,5 +27,6 @@ interface GalleryView : QkView<GalleryState> {
fun optionsItemSelected(): Observable<Int>
fun screenTouched(): Observable<*>
fun pageChanged(): Observable<MmsPart>
fun requestStoragePermission()
fun permissionResult(): Observable<*>
}
\ No newline at end of file
......@@ -25,6 +25,7 @@ import com.moez.QKSMS.common.base.QkViewModel
import com.moez.QKSMS.common.util.extensions.makeToast
import com.moez.QKSMS.extensions.mapNotNull
import com.moez.QKSMS.interactor.SaveImage
import com.moez.QKSMS.manager.PermissionManager
import com.moez.QKSMS.repository.ConversationRepository
import com.moez.QKSMS.repository.MessageRepository
import com.uber.autodispose.kotlin.autoDisposable
......@@ -39,7 +40,8 @@ class GalleryViewModel @Inject constructor(
messageRepo: MessageRepository,
@Named("partId") private val partId: Long,
private val context: Context,
private val saveImage: SaveImage
private val saveImage: SaveImage,
private val permissionManager: PermissionManager
) : QkViewModel<GalleryView, GalleryState>(GalleryState()) {
init {
......@@ -53,7 +55,13 @@ class GalleryViewModel @Inject constructor(
override fun bindView(view: GalleryView) {
super.bindView(view)
view.permissionResult()
.map { permissionManager.hasStorage() }
.autoDisposable(view.scope())
.subscribe{
if(permissionManager.hasStorage())
saveImage.execute(partId) { context.makeToast(R.string.gallery_toast_saved) }
}
// When the screen is touched, toggle the visibility of the navigation UI
view.screenTouched()
.withLatestFrom(state) { _, state -> state.navigationVisible }
......@@ -66,7 +74,13 @@ class GalleryViewModel @Inject constructor(
.filter { itemId -> itemId == R.id.save }
.withLatestFrom(view.pageChanged()) { _, part -> part.id }
.autoDisposable(view.scope())
.subscribe { partId -> saveImage.execute(partId) { context.makeToast(R.string.gallery_toast_saved) } }
.subscribe {
partId ->
if(permissionManager.hasStorage())
saveImage.execute(partId) { context.makeToast(R.string.gallery_toast_saved) }
else
view.requestStoragePermission()
}
}
}
\ No newline at end of file
......@@ -25,6 +25,7 @@ import dagger.Module
import dagger.Provides
import dagger.multibindings.IntoMap
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Named
@Module
class MainActivityModule {
......@@ -33,6 +34,11 @@ class MainActivityModule {
@ActivityScope
fun provideCompositeDiposableLifecycle(): CompositeDisposable = CompositeDisposable()
@Provides
@Named("threadId")
fun provideThreadId(activity: MainActivity): Long = activity.intent.extras?.getLong("threadId")
?: 0L
@Provides
@IntoMap
@ViewModelKey(MainViewModel::class)
......
......@@ -39,24 +39,27 @@ import io.reactivex.schedulers.Schedulers
import io.realm.Realm
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Named
class MainViewModel @Inject constructor(
markAllSeen: MarkAllSeen,
migratePreferences: MigratePreferences,
syncRepository: SyncRepository,
private val conversationRepo: ConversationRepository,
private val deleteConversations: DeleteConversations,
private val markArchived: MarkArchived,
private val markBlocked: MarkBlocked,
private val markPinned: MarkPinned,
private val markRead: MarkRead,
private val markUnarchived: MarkUnarchived,
private val markUnpinned: MarkUnpinned,
private val markUnread: MarkUnread,
private val navigator: Navigator,
private val permissionManager: PermissionManager,
private val prefs: Preferences,
private val syncMessages: SyncMessages
@Named("threadId") private val threadId: Long,
markAllSeen: MarkAllSeen,
migratePreferences: MigratePreferences,
syncRepository: SyncRepository,
private val conversationRepo: ConversationRepository,
private val deleteConversations: DeleteConversations,
private val markArchived: MarkArchived,
private val markBlocked: MarkBlocked,
private val markPinned: MarkPinned,
private val markRead: MarkRead,
private val markUnarchived: MarkUnarchived,
private val markUnpinned: MarkUnpinned,
private val markUnread: MarkUnread,
private val navigator: Navigator,
private val permissionManager: PermissionManager,
private val prefs: Preferences,
private val syncMessages: SyncMessages,
private val syncContacts: ContactSync
) : QkViewModel<MainView, MainState>(MainState(page = Inbox(data = conversationRepo.getConversations()))) {
init {
......@@ -301,6 +304,11 @@ class MainViewModel @Inject constructor(
}
.autoDisposable(view.scope())
.subscribe()
if (threadId == 0L) {
syncContacts.execute(Unit)
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment