Skip to content
Snippets Groups Projects
Commit 5b72e1cd authored by Adrien Béraud's avatar Adrien Béraud
Browse files

tv: allow to import archive

Change-Id: Ie1742017450c0c728c2ecd582b620cc602e6c4b9
parent 09d9b9eb
No related branches found
No related tags found
No related merge requests found
Showing
with 268 additions and 16 deletions
......@@ -98,6 +98,7 @@ class HomeAccountCreationFragment :
override fun onDestroyView() {
super.onDestroyView()
mCompositeDisposable.dispose()
binding = null
}
......@@ -111,6 +112,10 @@ class HomeAccountCreationFragment :
.launch(Intent(requireContext(), LinkDeviceImportSideActivity::class.java))
}
override fun goToBackupAccountLink() {
TODO("Not yet implemented")
}
override fun goToAccountConnect() {
replaceFragmentWithSlide(JamiAccountConnectFragment(), JamiAccountConnectFragment.TAG, R.id.wizard_container)
}
......
......@@ -83,6 +83,8 @@ class TVAccountWizard : BaseActivity<AccountWizardPresenter>(), AccountWizardVie
if (!model.managementServer.isNullOrEmpty()) {
presenter.initJamiAccountConnect(model, defaultAccountName)
mJamsAccount = true
} else if (model.archive != null) {
presenter.initJamiAccountBackup(model, getText(R.string.ring_account_default_name).toString())
} else {
presenter.initJamiAccountCreation(model, defaultAccountName)
mJamsAccount = false
......
......@@ -17,41 +17,85 @@
package cx.ring.tv.account
import android.app.Activity
import android.app.Instrumentation
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.activityViewModels
import androidx.leanback.widget.GuidanceStylist.Guidance
import androidx.leanback.widget.GuidedAction
import cx.ring.R
import cx.ring.account.AccountCreationViewModel
import dagger.hilt.android.AndroidEntryPoint
import androidx.activity.result.contract.ActivityResultContracts
import com.google.android.material.snackbar.Snackbar
import cx.ring.account.HomeAccountCreationFragment
import cx.ring.account.JamiImportBackupFragment
import cx.ring.utils.AndroidFileUtils.getCacheFile
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import net.jami.account.HomeAccountCreationPresenter
import net.jami.account.HomeAccountCreationView
import net.jami.model.AccountCreationModel
import java.io.File
@AndroidEntryPoint
class TVHomeAccountCreationFragment : JamiGuidedStepFragment<HomeAccountCreationPresenter, HomeAccountCreationView>(),
HomeAccountCreationView {
private val model: AccountCreationViewModel by activityViewModels()
private val mCompositeDisposable = CompositeDisposable()
override fun goToAccountCreation() {
add(parentFragmentManager, TVJamiAccountCreationFragment())
private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
finish()
}
}
override fun goToAccountLink() {
startActivityForResult(Intent(requireContext(), TVImportWizard::class.java), 56)
private val selectFile = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
Log.w(TAG, "Selected file: $uri")
if (uri == null) {
return@registerForActivityResult
}
getCacheFile(requireContext(), uri)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ file: File ->
model.model.archive = file
Log.w(TAG, "Loaded file: $file")
presenter.clickOnBackupAccountLink()
}) { e: Throwable ->
Log.e(HomeAccountCreationFragment.Companion.TAG, "Error importing archive", e)
view?.let { view ->
Snackbar.make(
view,
getString(R.string.import_archive_error),
Snackbar.LENGTH_LONG
).show()
}
}.let { mCompositeDisposable.add(it) }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == 56 && resultCode == Activity.RESULT_OK) {
private fun finish(){
activity?.finish()
}
override fun goToAccountCreation() {
add(parentFragmentManager, TVJamiAccountCreationFragment())
}
override fun goToAccountLink() {
startForResult.launch(Intent(requireContext(), TVImportWizard::class.java))
}
override fun goToAccountConnect() {
add(parentFragmentManager, TVJamiAccountConnectFragment())
}
override fun goToBackupAccountLink() {
Log.w(TAG, "goToBackupAccountLink")
add(parentFragmentManager, TVJamiLinkAccountFragment())
}
override fun goToSIPAccountCreation() {
//TODO
}
......@@ -68,17 +112,16 @@ class TVHomeAccountCreationFragment : JamiGuidedStepFragment<HomeAccountCreation
override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
val context = requireContext()
addAction(context, actions, LINK_ACCOUNT, getString(R.string.account_link_button), "", true)
addAction(context, actions, CREATE_ACCOUNT, getString(R.string.account_create_title), "", true)
addAction(
context, actions, CREATE_JAMS_ACCOUNT,
getString(R.string.account_connect_server_button), "", true
)
addAction(context, actions, LINK_ACCOUNT, getString(R.string.account_link_device), "", true)
addAction(context, actions, LINK_BACKUP_ACCOUNT, getString(R.string.account_link_archive_button), "", true)
addAction(context, actions, CREATE_JAMS_ACCOUNT, getString(R.string.account_connect_server_button), "", true)
}
override fun onGuidedActionClicked(action: GuidedAction) {
when (action.id) {
LINK_ACCOUNT -> presenter.clickOnLinkAccount()
LINK_BACKUP_ACCOUNT -> selectFile.launch("*/*")
CREATE_ACCOUNT -> presenter.clickOnCreateAccount()
CREATE_JAMS_ACCOUNT -> presenter.clickOnConnectAccount()
else -> requireActivity().finish()
......@@ -86,8 +129,13 @@ class TVHomeAccountCreationFragment : JamiGuidedStepFragment<HomeAccountCreation
}
companion object {
private const val TAG = "TVHomeAccountCreationFragment"
private const val LINK_ACCOUNT = 0L
private const val CREATE_ACCOUNT = 1L
private const val CREATE_JAMS_ACCOUNT = 2L
private const val LINK_BACKUP_ACCOUNT = 1L
private const val CREATE_ACCOUNT = 2L
private const val CREATE_JAMS_ACCOUNT = 3L
private const val REQUEST_CODE_IMPORT = 56
}
}
\ No newline at end of file
......@@ -16,7 +16,6 @@
*/
package cx.ring.tv.account
import android.app.Activity
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
......
/*
* Copyright (C) 2004-2025 Savoir-faire Linux Inc.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package cx.ring.tv.account
import android.graphics.Bitmap
import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.leanback.widget.GuidanceStylist.Guidance
import androidx.leanback.widget.GuidedAction
import cx.ring.R
import cx.ring.account.AccountCreationViewModel
import dagger.hilt.android.AndroidEntryPoint
import net.jami.account.JamiLinkAccountPresenter
import net.jami.account.JamiLinkAccountView
import net.jami.utils.StringUtils.toPassword
@AndroidEntryPoint
class TVJamiLinkAccountFragment : JamiGuidedStepFragment<JamiLinkAccountPresenter, JamiLinkAccountView>(),
JamiLinkAccountView {
private val model: AccountCreationViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val m = model.model
presenter.init(m)
if (m.photo != null) {
guidanceStylist.iconView?.setImageBitmap(m.photo as Bitmap?)
}
}
override fun onCreateGuidance(savedInstanceState: Bundle?): Guidance = Guidance(
getString(R.string.account_link_archive_button),
getString(R.string.help_password_enter),
"",
requireContext().getDrawable(R.drawable.ic_contact_picture_fallback)
)
override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
val context = requireContext()
addPasswordAction(context, actions, PASSWORD, getString(R.string.account_enter_password), "", "")
addDisabledAction(context, actions, LINK, getString(R.string.import_side_main_title), "", null, true)
}
override fun onProvideTheme(): Int = R.style.Theme_Ring_Leanback_GuidedStep_First
override fun onGuidedActionClicked(action: GuidedAction) {
if (action.id == LINK) {
presenter.linkClicked()
}
}
override fun enableLinkButton(enable: Boolean) {
findActionPositionById(LINK).takeUnless { it == -1 }?.also { position ->
actions[position]?.isEnabled = enable
notifyActionChanged(position)
}
}
override fun showPin(show: Boolean) {}
override fun createAccount() {
(activity as TVAccountWizard?)?.createAccount()
}
override fun onGuidedActionEditedAndProceed(action: GuidedAction): Long {
val password = action.editDescription.toString()
action.description = if (password.isNotEmpty()) toPassword(password) else getString(R.string.account_enter_password)
when (action.id) {
PASSWORD -> {
notifyActionChanged(findActionPositionById(PASSWORD))
presenter.passwordChanged(password)
}
}
return GuidedAction.ACTION_ID_NEXT
}
override fun cancel() {
activity?.onBackPressedDispatcher?.onBackPressed()
}
companion object {
private const val PASSWORD = 1L
private const val LINK = 3L
}
}
\ No newline at end of file
......@@ -154,7 +154,7 @@ class AccountWizardPresenter @Inject constructor(
mCreatingAccount = false
view.displayGenericError()
} else {
view.goToProfileCreation()
view.finish(true)
}
}
}) {
......
......@@ -28,6 +28,10 @@ class HomeAccountCreationPresenter @Inject constructor() : RootPresenter<HomeAcc
view?.goToAccountLink()
}
fun clickOnBackupAccountLink() {
view?.goToBackupAccountLink()
}
fun clickOnConnectAccount() {
view?.goToAccountConnect()
}
......
......@@ -19,6 +19,7 @@ package net.jami.account
interface HomeAccountCreationView {
fun goToAccountCreation()
fun goToAccountLink()
fun goToBackupAccountLink()
fun goToAccountConnect()
fun goToSIPAccountCreation()
}
\ No newline at end of file
/*
* Copyright (C) 2004-2025 Savoir-faire Linux Inc.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.jami.account
import net.jami.model.AccountCreationModel
import net.jami.mvp.RootPresenter
import javax.inject.Inject
class JamiLinkAccountPresenter @Inject constructor() : RootPresenter<JamiLinkAccountView>() {
private var mAccountCreationModel: AccountCreationModel? = null
fun init(accountCreationModel: AccountCreationModel?) {
mAccountCreationModel = accountCreationModel
if (mAccountCreationModel == null) {
view?.cancel()
return
}
val hasArchive = mAccountCreationModel?.archive != null
val view = view
if (view != null) {
view.showPin(!hasArchive)
view.enableLinkButton(hasArchive)
}
}
fun passwordChanged(password: String) {
mAccountCreationModel?.password = password
showHideLinkButton()
}
fun pinChanged(pin: String) {
mAccountCreationModel?.pin = pin
showHideLinkButton()
}
fun resetPin() {
mAccountCreationModel?.pin = ""
showHideLinkButton()
}
fun linkClicked() {
if (isFormValid) {
view?.createAccount()
}
}
private fun showHideLinkButton() {
view?.enableLinkButton(isFormValid)
}
private val isFormValid: Boolean
get() = mAccountCreationModel?.archive != null || mAccountCreationModel!!.pin.isNotEmpty()
}
\ No newline at end of file
/*
* Copyright (C) 2004-2025 Savoir-faire Linux Inc.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.jami.account
import net.jami.model.AccountCreationModel
interface JamiLinkAccountView {
fun enableLinkButton(enable: Boolean)
fun showPin(show: Boolean)
fun createAccount()
fun cancel()
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment