diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0c4fe99b..58976e3e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -245,6 +245,10 @@
android:name=".ui.etebase.InvitationsActivity"
android:exported="false"
/>
+
{
+ val intent = MigrateV2Activity.newIntent(this, account)
+ startActivity(intent)
+ }
else -> return super.onOptionsItemSelected(item)
}
return true
diff --git a/app/src/main/java/com/etesync/syncadapter/ui/MigrateV2Activity.kt b/app/src/main/java/com/etesync/syncadapter/ui/MigrateV2Activity.kt
new file mode 100644
index 00000000..e15ff488
--- /dev/null
+++ b/app/src/main/java/com/etesync/syncadapter/ui/MigrateV2Activity.kt
@@ -0,0 +1,739 @@
+package com.etesync.syncadapter.ui
+
+import android.accounts.Account
+import android.accounts.AccountManager
+import android.app.Dialog
+import android.app.ProgressDialog
+import android.content.ContentResolver
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.provider.ContactsContract
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import androidx.activity.viewModels
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.*
+import at.bitfire.ical4android.Event
+import at.bitfire.ical4android.Task
+import at.bitfire.vcard4android.Contact
+import at.bitfire.vcard4android.ContactsStorageException
+import com.etebase.client.Account as EtebaseAccount
+import com.etebase.client.Client
+import com.etebase.client.Item
+import com.etebase.client.ItemMetadata
+import com.etesync.journalmanager.model.SyncEntry
+import com.etesync.syncadapter.*
+import com.etesync.syncadapter.model.*
+import com.etesync.syncadapter.resource.LocalAddressBook
+import com.etesync.syncadapter.resource.LocalCalendar
+import com.etesync.syncadapter.ui.etebase.*
+import com.etesync.syncadapter.ui.setup.CreateAccountFragment
+import com.etesync.syncadapter.ui.setup.LoginCredentials
+import com.google.android.material.textfield.TextInputEditText
+import com.google.android.material.textfield.TextInputLayout
+import net.cachapa.expandablelayout.ExpandableLayout
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+import okhttp3.RequestBody
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
+import java.io.StringReader
+import java.net.URI
+import java.util.*
+import kotlin.collections.HashMap
+
+class MigrateV2Activity : BaseActivity() {
+ private lateinit var accountV1: Account
+ private val model: AccountViewModel by viewModels()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ accountV1 = intent.extras!!.getParcelable(EXTRA_ACCOUNT)!!
+
+ setContentView(R.layout.etebase_fragment_activity)
+
+ if (savedInstanceState == null) {
+ setTitle(R.string.migrate_v2_wizard_welcome_title)
+ supportFragmentManager.commit {
+ replace(R.id.fragment_container, WizardWelcomeFragment(accountV1))
+ }
+ }
+ }
+
+ companion object {
+ private val EXTRA_ACCOUNT = "account"
+
+ fun newIntent(context: Context, account: Account): Intent {
+ val intent = Intent(context, MigrateV2Activity::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 WizardWelcomeFragment(private val accountV1: Account) : Fragment() {
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ val ret = inflater.inflate(R.layout.migrate_v2_wizard_welcome, container, false)
+
+ if (savedInstanceState == null) {
+ if (container != null) {
+ initUi(inflater, ret)
+ }
+ }
+
+ return ret
+ }
+
+ private fun initUi(inflater: LayoutInflater, v: View) {
+ v.findViewById