mirror of
https://github.com/etesync/android
synced 2025-02-02 10:51:10 +00:00
NewAccountWizard: add a new account setup wizard.
This commit is contained in:
parent
82ce1783bc
commit
db843d8798
@ -237,6 +237,10 @@
|
||||
android:name=".ui.etebase.CollectionActivity"
|
||||
android:exported="false"
|
||||
/>
|
||||
<activity
|
||||
android:name=".ui.etebase.NewAccountWizardActivity"
|
||||
android:exported="false"
|
||||
/>
|
||||
<activity
|
||||
android:name=".ui.etebase.InvitationsActivity"
|
||||
android:exported="false"
|
||||
|
@ -0,0 +1,212 @@
|
||||
package com.etesync.syncadapter.ui.etebase
|
||||
|
||||
import android.accounts.Account
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.ProgressBar
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.etebase.client.Collection
|
||||
import com.etebase.client.CollectionMetadata
|
||||
import com.etebase.client.FetchOptions
|
||||
import com.etebase.client.exceptions.EtebaseException
|
||||
import com.etesync.syncadapter.R
|
||||
import com.etesync.syncadapter.syncadapter.requestSync
|
||||
import com.etesync.syncadapter.ui.BaseActivity
|
||||
import org.jetbrains.anko.doAsync
|
||||
import org.jetbrains.anko.uiThread
|
||||
|
||||
class NewAccountWizardActivity : BaseActivity() {
|
||||
private lateinit var account: Account
|
||||
private val model: AccountViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
account = intent.extras!!.getParcelable(EXTRA_ACCOUNT)!!
|
||||
|
||||
setContentView(R.layout.etebase_collection_activity)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
setTitle(R.string.account_wizard_collections_title)
|
||||
model.loadAccount(this, account)
|
||||
supportFragmentManager.commit {
|
||||
replace(R.id.fragment_container, WizardCheckFragment())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EXTRA_ACCOUNT = "account"
|
||||
|
||||
fun newIntent(context: Context, account: Account): Intent {
|
||||
val intent = Intent(context, NewAccountWizardActivity::class.java)
|
||||
intent.putExtra(EXTRA_ACCOUNT, account)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun reportErrorHelper(context: Context, e: Throwable) {
|
||||
AlertDialog.Builder(context)
|
||||
.setIcon(R.drawable.ic_info_dark)
|
||||
.setTitle(R.string.exception)
|
||||
.setMessage(e.localizedMessage)
|
||||
.setPositiveButton(android.R.string.yes) { _, _ -> }.show()
|
||||
}
|
||||
|
||||
class WizardCheckFragment : Fragment() {
|
||||
private val model: AccountViewModel by activityViewModels()
|
||||
private val loadingModel: LoadingViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val ret = inflater.inflate(R.layout.account_wizard_check, container, false)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
if (container != null) {
|
||||
initUi(inflater, ret)
|
||||
model.observe(this, {
|
||||
checkAccountInit()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun initUi(inflater: LayoutInflater, v: View) {
|
||||
val button = v.findViewById<Button>(R.id.button_retry)
|
||||
val progress = v.findViewById<ProgressBar>(R.id.loading)
|
||||
button.setOnClickListener {
|
||||
checkAccountInit()
|
||||
}
|
||||
loadingModel.observe(this, {
|
||||
if (it) {
|
||||
progress.visibility = View.VISIBLE
|
||||
button.visibility = View.GONE
|
||||
} else {
|
||||
progress.visibility = View.GONE
|
||||
button.visibility = View.VISIBLE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun checkAccountInit() {
|
||||
val colMgr = model.value?.colMgr ?: return
|
||||
loadingModel.setLoading(true)
|
||||
doAsync {
|
||||
try {
|
||||
val collections = colMgr.list(FetchOptions().limit(1))
|
||||
uiThread {
|
||||
if (collections.data.size > 0) {
|
||||
activity?.finish()
|
||||
} else {
|
||||
parentFragmentManager.commit {
|
||||
replace(R.id.fragment_container, WizardFragment())
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
uiThread {
|
||||
reportErrorHelper(requireContext(), e)
|
||||
}
|
||||
} finally {
|
||||
uiThread {
|
||||
loadingModel.setLoading(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WizardFragment : Fragment() {
|
||||
private val model: AccountViewModel by activityViewModels()
|
||||
private val loadingModel: LoadingViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val ret = inflater.inflate(R.layout.account_wizard_collections, container, false)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
if (container != null) {
|
||||
initUi(inflater, ret)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun initUi(inflater: LayoutInflater, v: View) {
|
||||
v.findViewById<Button>(R.id.button_create).setOnClickListener {
|
||||
createCollections()
|
||||
}
|
||||
|
||||
v.findViewById<Button>(R.id.button_skip).setOnClickListener {
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
val buttons = v.findViewById<View>(R.id.buttons_holder)
|
||||
val progress = v.findViewById<ProgressBar>(R.id.loading)
|
||||
loadingModel.observe(this, {
|
||||
if (it) {
|
||||
progress.visibility = View.VISIBLE
|
||||
buttons.visibility = View.GONE
|
||||
} else {
|
||||
progress.visibility = View.GONE
|
||||
buttons.visibility = View.VISIBLE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun createCollections() {
|
||||
val accountHolder = model.value ?: return
|
||||
val colMgr = accountHolder.colMgr
|
||||
loadingModel.setLoading(true)
|
||||
|
||||
doAsync {
|
||||
try {
|
||||
val baseMeta = listOf(
|
||||
Pair("etebase.vcard", "My Contacts"),
|
||||
Pair("etebase.vevent", "My Calendar"),
|
||||
Pair("etebase.vtodo", "My Tasks"),
|
||||
)
|
||||
|
||||
baseMeta.forEach {
|
||||
val meta = CollectionMetadata(it.first, it.second)
|
||||
meta.mtime = System.currentTimeMillis()
|
||||
|
||||
val col = colMgr.create(meta, "")
|
||||
uploadCollection(accountHolder, col)
|
||||
}
|
||||
requestSync(requireContext(), accountHolder.account)
|
||||
activity?.finish()
|
||||
} catch (e: EtebaseException) {
|
||||
uiThread {
|
||||
reportErrorHelper(requireContext(), e)
|
||||
}
|
||||
} finally {
|
||||
uiThread {
|
||||
loadingModel.setLoading(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadCollection(accountHolder: AccountHolder, col: Collection) {
|
||||
val etebaseLocalCache = accountHolder.etebaseLocalCache
|
||||
val colMgr = accountHolder.colMgr
|
||||
colMgr.upload(col)
|
||||
synchronized(etebaseLocalCache) {
|
||||
etebaseLocalCache.collectionSet(colMgr, col)
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import androidx.fragment.app.DialogFragment
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.TASK_PROVIDERS
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.syncadapter.log.Logger
|
||||
import com.etesync.syncadapter.ui.etebase.NewAccountWizardActivity
|
||||
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration
|
||||
import com.etesync.syncadapter.utils.AndroidCompat
|
||||
import com.etesync.syncadapter.utils.TaskProviderHandling
|
||||
@ -42,14 +43,16 @@ class CreateAccountFragment : DialogFragment() {
|
||||
val config = requireArguments().getSerializable(KEY_CONFIG) as Configuration
|
||||
|
||||
val activity = requireActivity()
|
||||
if (createAccount(config.userName, config)) {
|
||||
val account = createAccount(config.userName, config)
|
||||
if (account != null) {
|
||||
activity.setResult(Activity.RESULT_OK)
|
||||
startActivity(NewAccountWizardActivity.newIntent(requireContext(), account))
|
||||
activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(InvalidAccountException::class)
|
||||
protected fun createAccount(accountName: String, config: Configuration): Boolean {
|
||||
protected fun createAccount(accountName: String, config: Configuration): Account? {
|
||||
val account = Account(accountName, App.accountType)
|
||||
|
||||
// create Android account
|
||||
@ -57,7 +60,7 @@ class CreateAccountFragment : DialogFragment() {
|
||||
|
||||
val accountManager = AccountManager.get(context)
|
||||
if (!accountManager.addAccountExplicitly(account, config.password, null))
|
||||
return false
|
||||
return null
|
||||
|
||||
AccountSettings.setUserData(accountManager, account, config.url, config.userName)
|
||||
|
||||
@ -86,7 +89,7 @@ class CreateAccountFragment : DialogFragment() {
|
||||
throw e
|
||||
}
|
||||
|
||||
return true
|
||||
return account
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
47
app/src/main/res/layout/account_wizard_check.xml
Normal file
47
app/src/main/res/layout/account_wizard_check.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/account_wizard_collections_title"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading"
|
||||
style="@android:style/Widget.Material.ProgressBar.Large"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateOnly="true"
|
||||
android:keepScreenOn="true" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_retry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/retry"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
72
app/src/main/res/layout/account_wizard_collections.xml
Normal file
72
app/src/main/res/layout/account_wizard_collections.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/account_wizard_collections_title"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/account_wizard_collections_body" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading"
|
||||
style="@android:style/Widget.Material.ProgressBar.Large"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateOnly="true"
|
||||
android:keepScreenOn="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons_holder"
|
||||
style="@style/stepper_nav_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_skip"
|
||||
style="@style/stepper_nav_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/skip" />
|
||||
|
||||
<Space
|
||||
style="@style/stepper_nav_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_create"
|
||||
style="@style/stepper_nav_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/create" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -18,8 +18,11 @@
|
||||
<string name="address_books_authority_title">Address books</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="manage_accounts">Manage accounts</string>
|
||||
<string name="please_wait">Please wait …</string>
|
||||
<string name="please_wait">Please wait…</string>
|
||||
<string name="send">Send</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="skip">Skip</string>
|
||||
<string name="retry">Retry</string>
|
||||
|
||||
<string name="notification_channel_crash_reports">Crash Reports</string>
|
||||
<string name="notification_channel_debugging">Debugging</string>
|
||||
@ -83,6 +86,10 @@
|
||||
<string name="accounts_showcase_add">You need to add an account in order to use EteSync. Click here to add one...</string>
|
||||
<string name="accounts_missing_permissions">Missing permissions: %s</string>
|
||||
|
||||
<!-- Account Wizard -->
|
||||
<string name="account_wizard_collections_title">Welcome to EteSync!</string>
|
||||
<string name="account_wizard_collections_body">In order to start using EteSync you need to create collections to store your data. Click "Create" to create a default calendar, address book and a task list for you.</string>
|
||||
|
||||
<!-- AccountUpdateService -->
|
||||
|
||||
<!-- AppSettingsActivity -->
|
||||
|
Loading…
Reference in New Issue
Block a user