Add support for import remote profile
This commit is contained in:
@@ -9,14 +9,14 @@ fun Context.errorDialogBuilder(@StringRes messageId: Int): MaterialAlertDialogBu
|
||||
return MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.error_title)
|
||||
.setMessage(messageId)
|
||||
.setPositiveButton(resources.getString(android.R.string.ok), null)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
}
|
||||
|
||||
fun Context.errorDialogBuilder(message: String): MaterialAlertDialogBuilder {
|
||||
return MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.error_title)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(resources.getString(android.R.string.ok), null)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
}
|
||||
|
||||
fun Context.errorDialogBuilder(exception: Throwable): MaterialAlertDialogBuilder {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.microsoft.appcenter.distribute.DistributeListener
|
||||
import com.microsoft.appcenter.distribute.ReleaseDetails
|
||||
import com.microsoft.appcenter.distribute.UpdateAction
|
||||
import com.microsoft.appcenter.utils.AppNameHelper
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.sfa.Application
|
||||
import io.nekohasekai.sfa.BuildConfig
|
||||
import io.nekohasekai.sfa.R
|
||||
@@ -37,6 +38,7 @@ import io.nekohasekai.sfa.constant.Status
|
||||
import io.nekohasekai.sfa.database.Settings
|
||||
import io.nekohasekai.sfa.databinding.ActivityMainBinding
|
||||
import io.nekohasekai.sfa.ktx.errorDialogBuilder
|
||||
import io.nekohasekai.sfa.ui.profile.NewProfileActivity
|
||||
import io.nekohasekai.sfa.ui.shared.AbstractActivity
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -80,6 +82,31 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback, DistributeL
|
||||
startAnalysis()
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
val uri = intent.data ?: return
|
||||
if (uri.scheme != "sing-box" || uri.host != "import-remote-profile") {
|
||||
return
|
||||
}
|
||||
val profile = try {
|
||||
Libbox.parseRemoteProfileImportLink(uri.toString())
|
||||
} catch (e: Exception) {
|
||||
errorDialogBuilder(e).show()
|
||||
return
|
||||
}
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.import_remote_profile)
|
||||
.setMessage(getString(R.string.import_remote_profile_message, profile.name, profile.host))
|
||||
.setPositiveButton(android.R.string.ok) { _,_ ->
|
||||
startActivity(Intent(this, NewProfileActivity::class.java).apply {
|
||||
putExtra("importName", profile.name)
|
||||
putExtra("importURL", profile.url)
|
||||
})
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun reconnect() {
|
||||
connection.reconnect()
|
||||
}
|
||||
@@ -104,7 +131,7 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback, DistributeL
|
||||
val builder = MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.analytics_title))
|
||||
.setMessage(getString(R.string.analytics_message))
|
||||
.setPositiveButton(getString(R.string.ok)) { _, _ ->
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
Settings.analyticsAllowed = Settings.ANALYSIS_ALLOWED
|
||||
startAnalysisInternal()
|
||||
@@ -258,7 +285,7 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback, DistributeL
|
||||
|
||||
override fun onServiceAlert(type: Alert, message: String?) {
|
||||
val builder = MaterialAlertDialogBuilder(this)
|
||||
builder.setPositiveButton(resources.getString(android.R.string.ok), null)
|
||||
builder.setPositiveButton(android.R.string.ok, null)
|
||||
when (type) {
|
||||
Alert.RequestVPNPermission -> {
|
||||
builder.setMessage(getString(R.string.service_error_missing_permission))
|
||||
|
||||
@@ -12,11 +12,15 @@ import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.nekohasekai.libbox.Libbox
|
||||
import io.nekohasekai.sfa.R
|
||||
import io.nekohasekai.sfa.database.Profile
|
||||
import io.nekohasekai.sfa.database.Profiles
|
||||
import io.nekohasekai.sfa.database.TypedProfile
|
||||
import io.nekohasekai.sfa.databinding.FragmentConfigurationBinding
|
||||
import io.nekohasekai.sfa.databinding.ViewConfigutationItemBinding
|
||||
import io.nekohasekai.sfa.ktx.errorDialogBuilder
|
||||
import io.nekohasekai.sfa.ui.MainActivity
|
||||
import io.nekohasekai.sfa.ui.profile.EditProfileActivity
|
||||
import io.nekohasekai.sfa.ui.profile.NewProfileActivity
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -152,12 +156,32 @@ class ConfigurationFragment : Fragment() {
|
||||
intent.putExtra("profile_id", profile.id)
|
||||
it.context.startActivity(intent)
|
||||
}
|
||||
binding.moreButton.setOnClickListener { it ->
|
||||
val popup = PopupMenu(it.context, it)
|
||||
binding.moreButton.setOnClickListener { button ->
|
||||
val popup = PopupMenu(button.context, button)
|
||||
popup.setForceShowIcon(true)
|
||||
popup.menuInflater.inflate(R.menu.profile_menu, popup.menu)
|
||||
if (profile.typed.type != TypedProfile.Type.Remote) {
|
||||
popup.menu.removeItem(R.id.action_share)
|
||||
}
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.action_share -> {
|
||||
try {
|
||||
val link = Libbox.generateRemoteProfileImportLink(
|
||||
profile.name,
|
||||
profile.typed.remoteURL
|
||||
)
|
||||
button.context.startActivity(Intent.createChooser(Intent(android.content.Intent.ACTION_SEND).apply {
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_SUBJECT, "Share profile ${profile.name}")
|
||||
putExtra(Intent.EXTRA_TEXT, link)
|
||||
}, "Share"))
|
||||
} catch (e: Exception) {
|
||||
button.context.errorDialogBuilder(e).show()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_delete -> {
|
||||
adapter.items.remove(profile)
|
||||
adapter.notifyItemRemoved(adapterPosition)
|
||||
|
||||
@@ -82,6 +82,13 @@ class NewProfileActivity : AbstractActivity() {
|
||||
startFilesForResult(importFile, "application/json")
|
||||
}
|
||||
binding.createProfile.setOnClickListener(this::createProfile)
|
||||
intent.getStringExtra("importName")?.also { importName ->
|
||||
intent.getStringExtra("importURL") ?.also { importURL ->
|
||||
binding.name.editText?.setText(importName)
|
||||
binding.type.text = TypedProfile.Type.Remote.name
|
||||
binding.remoteURL.editText?.setText(importURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createProfile(view: View) {
|
||||
|
||||
Reference in New Issue
Block a user