mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 05:23:12 -07:00
Finish Settings Import on Android
This commit is contained in:
parent
2aa297d203
commit
5ddf9ef373
5 changed files with 111 additions and 10 deletions
|
@ -28,6 +28,7 @@ abstract class AppDatabase: RoomDatabase()
|
||||||
{
|
{
|
||||||
abstract fun registeredHostDao(): RegisteredHostDao
|
abstract fun registeredHostDao(): RegisteredHostDao
|
||||||
abstract fun manualHostDao(): ManualHostDao
|
abstract fun manualHostDao(): ManualHostDao
|
||||||
|
abstract fun importDao(): ImportDao
|
||||||
}
|
}
|
||||||
|
|
||||||
private var database: AppDatabase? = null
|
private var database: AppDatabase? = null
|
||||||
|
|
|
@ -24,11 +24,18 @@ import android.net.Uri
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
|
import androidx.room.*
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.metallic.chiaki.R
|
import com.metallic.chiaki.R
|
||||||
import com.squareup.moshi.*
|
import com.squareup.moshi.*
|
||||||
|
import io.reactivex.Completable
|
||||||
|
import io.reactivex.Flowable
|
||||||
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.rxkotlin.Singles
|
import io.reactivex.rxkotlin.Singles
|
||||||
|
import io.reactivex.rxkotlin.addTo
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import okio.Okio
|
import okio.Okio
|
||||||
|
@ -155,8 +162,17 @@ fun exportAndShareAllSettings(activity: Activity): Disposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun importSettingsFromUri(activity: Activity, uri: Uri)
|
fun importSettingsFromUri(activity: Activity, uri: Uri, disposable: CompositeDisposable)
|
||||||
{
|
{
|
||||||
|
fun loadFail(msg: String)
|
||||||
|
{
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setMessage(activity.getString(R.string.alert_message_import_failed, msg))
|
||||||
|
.setPositiveButton(R.string.action_import_failed_ack) { _, _ -> }
|
||||||
|
.create()
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
val inputStream = activity.contentResolver.openInputStream(uri) ?: throw IOException()
|
val inputStream = activity.contentResolver.openInputStream(uri) ?: throw IOException()
|
||||||
|
@ -187,19 +203,96 @@ fun importSettingsFromUri(activity: Activity, uri: Uri)
|
||||||
if(version != VERSION) // Add migrations here when necessary
|
if(version != VERSION) // Add migrations here when necessary
|
||||||
throw IOException("Value of version is invalid")
|
throw IOException("Value of version is invalid")
|
||||||
|
|
||||||
val settings = adapter.fromJsonValue(settingsValue)
|
val settings = adapter.fromJsonValue(settingsValue) ?: throw JsonDataException("Failed to parse Settings JSON")
|
||||||
Log.i("SerializedSettings", "would import: $settings")
|
Log.i("SerializedSettings", "would import: $settings")
|
||||||
// TODO: show dialog and import
|
|
||||||
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setMessage(activity.getString(R.string.alert_message_import,
|
||||||
|
settings.registeredHosts.let {
|
||||||
|
if(it.isEmpty())
|
||||||
|
"-"
|
||||||
|
else
|
||||||
|
it.joinToString(separator = "") { host -> "\n - ${host.ps4Nickname ?: "?"} / ${host.ps4Mac}" }
|
||||||
|
},
|
||||||
|
settings.manualHosts.let {
|
||||||
|
if(it.isEmpty())
|
||||||
|
"-"
|
||||||
|
else
|
||||||
|
it.joinToString(separator = "") { host -> "\n - ${host.host} / ${host.ps4Mac ?: "unregistered"}" }
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.setTitle(R.string.alert_title_import)
|
||||||
|
.setNegativeButton(R.string.action_import_cancel) { _, _ -> }
|
||||||
|
.setPositiveButton(R.string.action_import_import) { _, _ ->
|
||||||
|
getDatabase(activity).importDao()
|
||||||
|
.importCompletable(settings)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe()
|
||||||
|
.addTo(disposable)
|
||||||
|
}
|
||||||
|
.create()
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
catch(e: IOException)
|
catch(e: IOException)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
loadFail(e.message ?: "")
|
||||||
}
|
}
|
||||||
catch(e: JsonDataException)
|
catch(e: JsonDataException)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
loadFail(e.message ?: "")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
@Dao
|
||||||
|
abstract class ImportDao
|
||||||
|
{
|
||||||
|
@Insert
|
||||||
|
abstract fun insertRegisteredHosts(hosts: List<RegisteredHost>)
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
abstract fun insertManualHosts(hosts: List<ManualHost>)
|
||||||
|
|
||||||
|
class IdWithMac(val id: Long, val mac: MacAddress)
|
||||||
|
|
||||||
|
@Query("SELECT id, ps4_mac AS mac FROM registered_host WHERE ps4_mac IN (:macs)")
|
||||||
|
abstract fun registeredHostsByMac(macs: List<MacAddress>): List<IdWithMac>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
fun import(settings: SerializedSettings)
|
||||||
|
{
|
||||||
|
insertRegisteredHosts(
|
||||||
|
settings.registeredHosts.map {
|
||||||
|
RegisteredHost(
|
||||||
|
apSsid = it.apSsid,
|
||||||
|
apBssid = it.apBssid,
|
||||||
|
apKey = it.apKey,
|
||||||
|
apName = it.apName,
|
||||||
|
ps4Mac = it.ps4Mac,
|
||||||
|
ps4Nickname = it.ps4Nickname,
|
||||||
|
rpRegistKey = it.rpRegistKey,
|
||||||
|
rpKeyType = it.rpKeyType,
|
||||||
|
rpKey = it.rpKey
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
val macs = settings.manualHosts.mapNotNull { it.ps4Mac }
|
||||||
|
val idMacs =
|
||||||
|
if(macs.isNotEmpty())
|
||||||
|
registeredHostsByMac(macs)
|
||||||
|
else
|
||||||
|
listOf()
|
||||||
|
|
||||||
|
insertManualHosts(
|
||||||
|
settings.manualHosts.map {
|
||||||
|
ManualHost(
|
||||||
|
host = it.host,
|
||||||
|
registeredHost = idMacs.firstOrNull { regHost -> regHost.mac == it.ps4Mac }?.id
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ImportDao.importCompletable(settings: SerializedSettings) = Completable.fromCallable { import(settings) }
|
||||||
|
|
|
@ -90,6 +90,7 @@ class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private var disposable = CompositeDisposable()
|
private var disposable = CompositeDisposable()
|
||||||
|
private var exportDisposable = CompositeDisposable().also { it.addTo(disposable) }
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?)
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?)
|
||||||
{
|
{
|
||||||
|
@ -149,8 +150,8 @@ class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
private fun exportSettings()
|
private fun exportSettings()
|
||||||
{
|
{
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
disposable.clear()
|
exportDisposable.clear()
|
||||||
exportAndShareAllSettings(activity).addTo(disposable)
|
exportAndShareAllSettings(activity).addTo(exportDisposable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun importSettings()
|
private fun importSettings()
|
||||||
|
@ -168,7 +169,7 @@ class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
{
|
{
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
data?.data?.also {
|
data?.data?.also {
|
||||||
importSettingsFromUri(activity, it)
|
importSettingsFromUri(activity, it, disposable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,12 @@
|
||||||
<string name="alert_regist_duplicate">The console with MAC %s has already been registered. Should the previous record be overwritten?</string>
|
<string name="alert_regist_duplicate">The console with MAC %s has already been registered. Should the previous record be overwritten?</string>
|
||||||
<string name="action_regist_overwrite">Overwrite</string>
|
<string name="action_regist_overwrite">Overwrite</string>
|
||||||
<string name="action_regist_discard">Cancel</string>
|
<string name="action_regist_discard">Cancel</string>
|
||||||
|
<string name="action_import_import">Import</string>
|
||||||
|
<string name="action_import_cancel">Cancel</string>
|
||||||
|
<string name="alert_title_import">Import</string>
|
||||||
|
<string name="alert_message_import">Registered Hosts: %s\n\nManual Hosts: %s</string>
|
||||||
|
<string name="alert_message_import_failed">Failed to import settings from file:\n%s</string>
|
||||||
|
<string name="action_import_failed_ack">Dismiss</string>
|
||||||
<string name="title_edit_manual">Manual Console Entry</string>
|
<string name="title_edit_manual">Manual Console Entry</string>
|
||||||
<string name="action_add_manual_save">Save</string>
|
<string name="action_add_manual_save">Save</string>
|
||||||
<string name="hint_add_manual_regist_host">Registered Console</string>
|
<string name="hint_add_manual_regist_host">Registered Console</string>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.60'
|
ext.kotlin_version = '1.3.61'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue