@@ -6,24 +6,35 @@ import android.content.Intent
66import android.net.Uri
77import android.provider.Settings
88import androidx.activity.result.contract.ActivityResultContracts
9+ import androidx.lifecycle.lifecycleScope
910import com.github.kr328.clash.common.constants.Intents
1011import com.github.kr328.clash.common.util.intent
1112import com.github.kr328.clash.common.util.setUUID
1213import com.github.kr328.clash.design.NewProfileDesign
14+ import com.github.kr328.clash.design.R
1315import com.github.kr328.clash.design.model.ProfileProvider
16+ import com.github.kr328.clash.design.util.showExceptionToast
1417import com.github.kr328.clash.service.model.Profile
1518import com.github.kr328.clash.util.withProfile
19+ import io.github.g00fy2.quickie.QRResult
20+ import io.github.g00fy2.quickie.QRResult.QRError
21+ import io.github.g00fy2.quickie.QRResult.QRMissingPermission
22+ import io.github.g00fy2.quickie.QRResult.QRSuccess
23+ import io.github.g00fy2.quickie.QRResult.QRUserCanceled
24+ import io.github.g00fy2.quickie.ScanQRCode
1625import kotlinx.coroutines.Dispatchers
1726import kotlinx.coroutines.isActive
27+ import kotlinx.coroutines.launch
1828import kotlinx.coroutines.selects.select
1929import kotlinx.coroutines.withContext
2030import java.util.*
21- import com.github.kr328.clash.design.R
2231
2332class NewProfileActivity : BaseActivity <NewProfileDesign >() {
2433 private val self: NewProfileActivity
2534 get() = this
2635
36+ private val scanLauncher = registerForActivityResult(ScanQRCode (), ::scanResultHandler)
37+
2738 override suspend fun main () {
2839 val design = NewProfileDesign (this )
2940
@@ -45,8 +56,14 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
4556 val uuid: UUID ? = when (val p = it.provider) {
4657 is ProfileProvider .File ->
4758 create(Profile .Type .File , name)
59+
4860 is ProfileProvider .Url ->
4961 create(Profile .Type .Url , name)
62+
63+ is ProfileProvider .QR -> {
64+ null
65+ }
66+
5067 is ProfileProvider .External -> {
5168 val data = p.get()
5269
@@ -68,9 +85,14 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
6885 launchProperties(uuid)
6986 }
7087 }
88+
7189 is NewProfileDesign .Request .OpenDetail -> {
7290 launchAppDetailed(it.provider)
7391 }
92+
93+ is NewProfileDesign .Request .LaunchScanner -> {
94+ scanLauncher.launch(null )
95+ }
7496 }
7597 }
7698 }
@@ -138,7 +160,41 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
138160 ProfileProvider .External (name.toString(), summary.toString(), icon, intent)
139161 }
140162
141- listOf (ProfileProvider .File (self), ProfileProvider .Url (self)) + providers
163+ listOf (
164+ ProfileProvider .File (self),
165+ ProfileProvider .Url (self),
166+ ProfileProvider .QR (self)
167+ ) + providers
142168 }
143169 }
170+
171+ private fun scanResultHandler (result : QRResult ) {
172+ lifecycleScope.launch {
173+ when (result) {
174+ is QRSuccess -> {
175+ val url = result.content.rawValue
176+ ? : result.content.rawBytes?.let { String (it) }.orEmpty()
177+
178+ createProfileByQrCode(url)
179+ }
180+
181+ QRUserCanceled -> {}
182+ QRMissingPermission -> design?.showExceptionToast(getString(R .string.import_from_qr_no_permission))
183+ is QRError -> design?.showExceptionToast(getString(R .string.import_from_qr_exception))
184+ }
185+ }
186+ }
187+
188+ private suspend fun createProfileByQrCode (url : String ) {
189+ withProfile {
190+ launchProperties(
191+ create(
192+ type = Profile .Type .Url ,
193+ name = getString(R .string.new_profile),
194+ url,
195+ )
196+ )
197+ }
198+ }
199+
144200}
0 commit comments