BackupController.kt 7.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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.feature.backup

21 22
import android.Manifest
import android.app.Activity
Moez Bhatti's avatar
Moez Bhatti committed
23
import android.content.res.ColorStateList
Moez Bhatti's avatar
Moez Bhatti committed
24
import android.graphics.Typeface
25
import android.view.View
26
import androidx.appcompat.app.AlertDialog
27
import androidx.core.app.ActivityCompat
Moez Bhatti's avatar
Moez Bhatti committed
28
import androidx.core.view.children
29
import androidx.core.view.isVisible
30 31 32
import com.jakewharton.rxbinding2.view.clicks
import com.moez.QKSMS.R
import com.moez.QKSMS.common.base.QkController
Moez Bhatti's avatar
Moez Bhatti committed
33
import com.moez.QKSMS.common.util.DateFormatter
34
import com.moez.QKSMS.common.util.extensions.getLabel
35
import com.moez.QKSMS.common.util.extensions.setBackgroundTint
36
import com.moez.QKSMS.common.util.extensions.setPositiveButton
37
import com.moez.QKSMS.common.util.extensions.setTint
Moez Bhatti's avatar
Moez Bhatti committed
38
import com.moez.QKSMS.common.widget.PreferenceView
39
import com.moez.QKSMS.injection.appComponent
40
import com.moez.QKSMS.model.BackupFile
41
import com.moez.QKSMS.repository.BackupRepository
42
import io.reactivex.Observable
43 44
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
45
import kotlinx.android.synthetic.main.backup_controller.*
46
import kotlinx.android.synthetic.main.backup_list_dialog.view.*
Moez Bhatti's avatar
Moez Bhatti committed
47
import kotlinx.android.synthetic.main.preference_view.view.*
48 49 50 51
import javax.inject.Inject

class BackupController : QkController<BackupView, BackupState, BackupPresenter>(), BackupView {

52
    @Inject lateinit var adapter: BackupAdapter
Moez Bhatti's avatar
Moez Bhatti committed
53
    @Inject lateinit var dateFormatter: DateFormatter
54 55
    @Inject override lateinit var presenter: BackupPresenter

56
    private val activityVisibleSubject: Subject<Unit> = PublishSubject.create()
57 58 59 60
    private val confirmRestoreSubject: Subject<Unit> = PublishSubject.create()
    private val stopRestoreSubject: Subject<Unit> = PublishSubject.create()

    private val backupFilesDialog by lazy {
61 62 63
        val view = View.inflate(activity, R.layout.backup_list_dialog, null)
                .apply { files.adapter = adapter.apply { emptyView = empty } }

64
        AlertDialog.Builder(activity!!)
65 66 67 68
                .setView(view)
                .setCancelable(true)
                .create()
    }
69

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    private val confirmRestoreDialog by lazy {
        AlertDialog.Builder(activity!!)
                .setTitle(R.string.backup_restore_confirm_title)
                .setMessage(R.string.backup_restore_confirm_message)
                .setPositiveButton(R.string.backup_restore_title, confirmRestoreSubject)
                .setNegativeButton(R.string.button_cancel, null)
                .create()
    }

    private val stopRestoreDialog by lazy {
        AlertDialog.Builder(activity!!)
                .setTitle(R.string.backup_restore_stop_title)
                .setMessage(R.string.backup_restore_stop_message)
                .setPositiveButton(R.string.button_stop, stopRestoreSubject)
                .setNegativeButton(R.string.button_cancel, null)
                .create()
    }

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    init {
        appComponent.inject(this)
        layoutRes = R.layout.backup_controller
    }

    override fun onAttach(view: View) {
        super.onAttach(view)
        presenter.bindIntents(this)
        setTitle(R.string.backup_title)
        showBackButton(true)
    }

    override fun onViewCreated() {
        super.onViewCreated()

        themedActivity?.colors?.theme()?.let { theme ->
Moez Bhatti's avatar
Moez Bhatti committed
104 105
            progressBar.indeterminateTintList = ColorStateList.valueOf(theme.theme)
            progressBar.progressTintList = ColorStateList.valueOf(theme.theme)
106 107 108 109
            fab.setBackgroundTint(theme.theme)
            fabIcon.setTint(theme.textPrimary)
            fabLabel.setTextColor(theme.textPrimary)
        }
Moez Bhatti's avatar
Moez Bhatti committed
110 111 112 113 114 115

        // Make the list titles bold
        linearLayout.children
                .mapNotNull { it as? PreferenceView }
                .map { it.titleView }
                .forEach { it.setTypeface(it.typeface, Typeface.BOLD) }
116 117
    }

118 119 120 121 122
    override fun onActivityResumed(activity: Activity) {
        super.onActivityResumed(activity)
        activityVisibleSubject.onNext(Unit)
    }

123
    override fun render(state: BackupState) {
124
        when {
125
            state.backupProgress.running -> {
126 127
                progressIcon.setImageResource(R.drawable.ic_file_upload_black_24dp)
                progressTitle.setText(R.string.backup_backing_up)
128
                progressSummary.text = state.backupProgress.getLabel(activity!!)
129
                progressSummary.isVisible = progressSummary.text.isNotEmpty()
Moez Bhatti's avatar
Moez Bhatti committed
130
                progressCancel.isVisible = false
131 132 133 134 135
                val running = (state.backupProgress as? BackupRepository.Progress.Running)
                progressBar.isVisible = state.backupProgress.indeterminate || running?.max ?: 0 > 0
                progressBar.isIndeterminate = state.backupProgress.indeterminate
                progressBar.max = running?.max ?: 0
                progressBar.progress = running?.count ?: 0
136 137 138 139
                progress.isVisible = true
                fab.isVisible = false
            }

140
            state.restoreProgress.running -> {
141 142
                progressIcon.setImageResource(R.drawable.ic_file_download_black_24dp)
                progressTitle.setText(R.string.backup_restoring)
143
                progressSummary.text = state.restoreProgress.getLabel(activity!!)
144
                progressSummary.isVisible = progressSummary.text.isNotEmpty()
Moez Bhatti's avatar
Moez Bhatti committed
145
                progressCancel.isVisible = true
146 147 148 149 150
                val running = (state.restoreProgress as? BackupRepository.Progress.Running)
                progressBar.isVisible = state.restoreProgress.indeterminate || running?.max ?: 0 > 0
                progressBar.isIndeterminate = state.restoreProgress.indeterminate
                progressBar.max = running?.max ?: 0
                progressBar.progress = running?.count ?: 0
151 152 153 154 155 156 157 158 159 160
                progress.isVisible = true
                fab.isVisible = false
            }

            else -> {
                progress.isVisible = false
                fab.isVisible = true
            }
        }

161
        backup.summary = state.lastBackup
Moez Bhatti's avatar
Moez Bhatti committed
162

163
        adapter.data = state.backups
164 165
    }

166 167
    override fun activityVisible(): Observable<*> = activityVisibleSubject

168 169
    override fun restoreClicks(): Observable<*> = restore.clicks()

170
    override fun restoreFileSelected(): Observable<BackupFile> = adapter.backupSelected
171 172 173 174 175 176 177
            .doOnNext { backupFilesDialog.dismiss() }

    override fun restoreConfirmed(): Observable<*> = confirmRestoreSubject

    override fun stopRestoreClicks(): Observable<*> = progressCancel.clicks()

    override fun stopRestoreConfirmed(): Observable<*> = stopRestoreSubject
178 179 180

    override fun fabClicks(): Observable<*> = fab.clicks()

181 182 183 184
    override fun requestStoragePermission() {
        ActivityCompat.requestPermissions(activity!!, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0)
    }

185 186 187 188 189
    override fun selectFile() = backupFilesDialog.show()

    override fun confirmRestore() = confirmRestoreDialog.show()

    override fun stopRestore() = stopRestoreDialog.show()
190 191

}