cleanup code & update version code
This commit is contained in:
20 files changed
+153
-100
No files matched your search
+2
-2
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "com.github.kr328.clash"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 29
|
||||
versionCode 10028
|
||||
versionName "1.0.28-alpha"
|
||||
versionCode 10029
|
||||
versionName "1.0.29-alpha"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.github.kr328.clash
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import com.github.kr328.clash.utils.ServiceUtils
|
||||
|
||||
class BootCompleteReceiver : BroadcastReceiver() {
|
||||
|
||||
@@ -54,7 +54,7 @@ class CreateProfileActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if ( requestCode == IMPORT_REQUEST_CODE && resultCode == Activity.RESULT_OK ) {
|
||||
if (requestCode == IMPORT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -25,9 +25,14 @@ class FeedbackActivity : BaseActivity() {
|
||||
onPreferenceClickListener = Preference.OnPreferenceClickListener { p ->
|
||||
val data = ClipData.newPlainText("userIdentifier", summary)
|
||||
|
||||
requireContext().getSystemService(ClipboardManager::class.java)?.setPrimaryClip(data)
|
||||
requireContext().getSystemService(ClipboardManager::class.java)
|
||||
?.setPrimaryClip(data)
|
||||
|
||||
Toast.makeText(requireContext(), R.string.feedback_feedback_id_copied, Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
R.string.feedback_feedback_id_copied,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@@ -6,18 +6,13 @@ import android.os.Bundle
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.charleskorn.kaml.Yaml
|
||||
import com.charleskorn.kaml.YamlConfiguration
|
||||
import com.charleskorn.kaml.YamlException
|
||||
import com.github.kr328.clash.adapter.FormAdapter
|
||||
import com.github.kr328.clash.model.ClashProfile
|
||||
import com.github.kr328.clash.service.data.ClashProfileEntity
|
||||
import com.github.kr328.clash.utils.FileUtils
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_import_url.*
|
||||
import java.io.FileOutputStream
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
import java.net.URL
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@@ -54,9 +49,10 @@ class ImportUrlActivity : BaseActivity() {
|
||||
checkAndInsert()
|
||||
}
|
||||
|
||||
if ( intent.action == Intent.ACTION_VIEW
|
||||
if (intent.action == Intent.ACTION_VIEW
|
||||
&& intent.data?.scheme == "clash"
|
||||
&& intent.data?.host == "install-config") {
|
||||
&& intent.data?.host == "install-config"
|
||||
) {
|
||||
(elements[1] as FormAdapter.TextType).content =
|
||||
intent.data?.getQueryParameter("url") ?: ""
|
||||
}
|
||||
@@ -78,11 +74,11 @@ class ImportUrlActivity : BaseActivity() {
|
||||
val name = elements[0] as FormAdapter.TextType
|
||||
val url = elements[1] as FormAdapter.TextType
|
||||
|
||||
if ( name.content.isBlank() ) {
|
||||
if (name.content.isBlank()) {
|
||||
return
|
||||
}
|
||||
|
||||
if ( url.content.isBlank() ) {
|
||||
if (url.content.isBlank()) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -94,7 +90,7 @@ class ImportUrlActivity : BaseActivity() {
|
||||
try {
|
||||
val connection = URL(url.content).openConnection()
|
||||
|
||||
val data = with (connection) {
|
||||
val data = with(connection) {
|
||||
connectTimeout = DEFAULT_TIMEOUT
|
||||
connect()
|
||||
|
||||
@@ -117,22 +113,29 @@ class ImportUrlActivity : BaseActivity() {
|
||||
|
||||
pipe[0].close()
|
||||
|
||||
if ( error != null )
|
||||
if (error != null)
|
||||
throw Exception(error)
|
||||
|
||||
val cache =
|
||||
FileUtils.generateRandomFile(filesDir.resolve(Constants.PROFILES_DIR), ".yaml")
|
||||
FileUtils.generateRandomFile(
|
||||
filesDir.resolve(Constants.PROFILES_DIR),
|
||||
".yaml"
|
||||
)
|
||||
|
||||
FileOutputStream(cache).use { outputStream ->
|
||||
outputStream.write(data.toByteArray())
|
||||
}
|
||||
|
||||
runClash { clash ->
|
||||
clash.profileService.addProfile(ClashProfileEntity(name.content,
|
||||
ClashProfileEntity.urlToken(url.content),
|
||||
cache.absolutePath,
|
||||
false,
|
||||
System.currentTimeMillis()))
|
||||
clash.profileService.addProfile(
|
||||
ClashProfileEntity(
|
||||
name.content,
|
||||
ClashProfileEntity.urlToken(url.content),
|
||||
cache.absolutePath,
|
||||
false,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
@@ -140,12 +143,15 @@ class ImportUrlActivity : BaseActivity() {
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
} catch (e: Exception) {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
activity_import_url_root,
|
||||
getString(R.string.clash_profile_invalid, e.message?.replace(YamlException::class.java.name + ":", "") ?: "Unknown"),
|
||||
getString(
|
||||
R.string.clash_profile_invalid,
|
||||
e.message?.replace(YamlException::class.java.name + ":", "")
|
||||
?: "Unknown"
|
||||
),
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
|
||||
@@ -155,8 +161,7 @@ class ImportUrlActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
} catch (e: Exception) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,11 @@ class LogActivity : BaseActivity() {
|
||||
activity_logs_list.adapter?.notifyDataSetChanged()
|
||||
|
||||
runClash {
|
||||
it.eventService.registerEventObserver(LogActivity::class.java.name,
|
||||
it.eventService.registerEventObserver(
|
||||
LogActivity::class.java.name,
|
||||
this,
|
||||
intArrayOf(Event.EVENT_LOG))
|
||||
intArrayOf(Event.EVENT_LOG)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,18 +72,20 @@ class LogActivity : BaseActivity() {
|
||||
handler.post {
|
||||
buffer.addFirst(event)
|
||||
|
||||
if ( syncLog ) {
|
||||
if (syncLog) {
|
||||
activity_logs_list.adapter!!.notifyItemInserted(0)
|
||||
if ( activity_logs_list.computeVerticalScrollOffset() < 30 )
|
||||
if (activity_logs_list.computeVerticalScrollOffset() < 30)
|
||||
activity_logs_list.scrollToPosition(0)
|
||||
}
|
||||
|
||||
if ( buffer.size() >= MAX_EVENT_COUNT ) {
|
||||
if (buffer.size() >= MAX_EVENT_COUNT) {
|
||||
buffer.removeFromEnd(buffer.size() - MAX_EVENT_COUNT - 1)
|
||||
|
||||
if ( syncLog ) {
|
||||
activity_logs_list.adapter?.notifyItemRangeRemoved(MAX_EVENT_COUNT - 1,
|
||||
buffer.size() - MAX_EVENT_COUNT - 1 )
|
||||
if (syncLog) {
|
||||
activity_logs_list.adapter?.notifyItemRangeRemoved(
|
||||
MAX_EVENT_COUNT - 1,
|
||||
buffer.size() - MAX_EVENT_COUNT - 1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,10 @@ class MainActivity : BaseActivity() {
|
||||
activity_main_clash_status_icon.setImageResource(R.drawable.ic_clash_started)
|
||||
activity_main_clash_status_title.text = getString(R.string.clash_status_started)
|
||||
activity_main_clash_status_summary.text =
|
||||
getString(R.string.clash_status_forwarded_traffic, ByteFormatter.byteToString(0))
|
||||
getString(
|
||||
R.string.clash_status_forwarded_traffic,
|
||||
ByteFormatter.byteToString(0)
|
||||
)
|
||||
activity_main_clash_proxies.visibility = View.VISIBLE
|
||||
activity_main_clash_logs.visibility = View.VISIBLE
|
||||
}
|
||||
@@ -116,7 +119,7 @@ class MainActivity : BaseActivity() {
|
||||
val general = it.queryGeneral()
|
||||
|
||||
runOnUiThread {
|
||||
when ( general.mode ) {
|
||||
when (general.mode) {
|
||||
General.Mode.DIRECT ->
|
||||
activity_main_clash_proxies_summary.text =
|
||||
getText(R.string.clash_proxy_manage_summary_direct)
|
||||
@@ -198,9 +201,11 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
private fun showAboutDialog() {
|
||||
val view = LayoutInflater.from(this).inflate(R.layout.dialog_about, window.decorView as ViewGroup?, false)
|
||||
val view = LayoutInflater.from(this)
|
||||
.inflate(R.layout.dialog_about, window.decorView as ViewGroup?, false)
|
||||
|
||||
view.findViewById<TextView>(android.R.id.summary).text = packageManager.getPackageInfo(packageName, 0).let(PackageInfo::versionName)
|
||||
view.findViewById<TextView>(android.R.id.summary).text =
|
||||
packageManager.getPackageInfo(packageName, 0).let(PackageInfo::versionName)
|
||||
|
||||
AlertDialog.Builder(this).setView(view).show()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.github.kr328.clash.core.utils.Log
|
||||
import com.google.firebase.FirebaseApp
|
||||
import io.fabric.sdk.android.Fabric
|
||||
import java.security.MessageDigest
|
||||
import kotlin.experimental.and
|
||||
|
||||
|
||||
class MainApplication : Application() {
|
||||
@@ -35,7 +34,7 @@ class MainApplication : Application() {
|
||||
return this.map {
|
||||
Integer.toHexString(it.toInt() and 0xff)
|
||||
}.map {
|
||||
if ( it.length < 2 )
|
||||
if (it.length < 2)
|
||||
"0$it"
|
||||
else
|
||||
it
|
||||
@@ -63,7 +62,7 @@ class MainApplication : Application() {
|
||||
Crashlytics.setBool(CRASHLYTICS_SPLIT_APK_KEY, detectSplitArchive())
|
||||
Crashlytics.setUserIdentifier(userIdentifier)
|
||||
|
||||
Log.handler = object: Log.LogHandler {
|
||||
Log.handler = object : Log.LogHandler {
|
||||
override fun info(message: String, throwable: Throwable?) {
|
||||
android.util.Log.i(Constants.TAG, message, throwable)
|
||||
}
|
||||
|
||||
@@ -9,19 +9,14 @@ import android.view.View
|
||||
import android.widget.PopupMenu
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.charleskorn.kaml.Yaml
|
||||
import com.charleskorn.kaml.YamlConfiguration
|
||||
import com.github.kr328.clash.adapter.ProfileAdapter
|
||||
import com.github.kr328.clash.core.event.ErrorEvent
|
||||
import com.github.kr328.clash.core.event.ProfileChangedEvent
|
||||
import com.github.kr328.clash.model.ClashProfile
|
||||
import com.github.kr328.clash.service.data.ClashProfileEntity
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_profiles.*
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Proxy
|
||||
import java.net.URL
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@@ -35,10 +30,12 @@ class ProfilesActivity : BaseActivity() {
|
||||
setSupportActionBar(activity_profiles_toolbar)
|
||||
|
||||
activity_profiles_main_list.layoutManager = LinearLayoutManager(this)
|
||||
activity_profiles_main_list.adapter = ProfileAdapter(this,
|
||||
activity_profiles_main_list.adapter = ProfileAdapter(
|
||||
this,
|
||||
this::onProfileClick,
|
||||
this::onOperateClick,
|
||||
this::onProfileLongClick) {
|
||||
this::onProfileLongClick
|
||||
) {
|
||||
startActivity(Intent(this, CreateProfileActivity::class.java))
|
||||
}
|
||||
}
|
||||
@@ -114,7 +111,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
|
||||
updateProfile(profile)
|
||||
updateProfile(profile)
|
||||
}
|
||||
ClashProfileEntity.isFileToken(profile.token) -> {
|
||||
Snackbar.make(
|
||||
@@ -150,7 +147,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
try {
|
||||
val connection = URL(url).openConnection()
|
||||
|
||||
val data = with (connection) {
|
||||
val data = with(connection) {
|
||||
connectTimeout = ImportUrlActivity.DEFAULT_TIMEOUT
|
||||
connect()
|
||||
|
||||
@@ -172,7 +169,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
|
||||
pipe[0].close()
|
||||
|
||||
if ( error != null )
|
||||
if (error != null)
|
||||
throw Exception(error)
|
||||
|
||||
FileOutputStream(profile.file).use { outputStream ->
|
||||
@@ -182,8 +179,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
runClash { clash ->
|
||||
clash.profileService.touchProfile(profile.id)
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
} catch (e: Exception) {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
activity_profiles_root,
|
||||
@@ -194,7 +190,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
if ( dialog?.isShowing == true )
|
||||
if (dialog?.isShowing == true)
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
@@ -202,6 +198,7 @@ class ProfilesActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
override fun onErrorEvent(event: ErrorEvent?) {
|
||||
Snackbar.make(activity_profiles_root, event?.message ?: "Unknown", Snackbar.LENGTH_LONG).show()
|
||||
Snackbar.make(activity_profiles_root, event?.message ?: "Unknown", Snackbar.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
@@ -39,18 +39,18 @@ class ProxyActivity : BaseActivity() {
|
||||
val adapter = (activity_proxies_list.adapter as ProxyAdapter)
|
||||
|
||||
runClash {
|
||||
val proxies = adapter.elements.subList(position, position+size)
|
||||
val proxies = adapter.elements.subList(position, position + size)
|
||||
.filterIsInstance<ListProxy.ListProxyItem>()
|
||||
.mapIndexed { index, proxy -> proxy.name to IndexedValue(index, proxy)}
|
||||
.mapIndexed { index, proxy -> proxy.name to IndexedValue(index, proxy) }
|
||||
.toMap()
|
||||
|
||||
for ((_, p) in proxies) {
|
||||
p.value.delay = -1
|
||||
}
|
||||
|
||||
it.startUrlTest(proxies.keys.toTypedArray(), object: IUrlTestCallback.Stub() {
|
||||
it.startUrlTest(proxies.keys.toTypedArray(), object : IUrlTestCallback.Stub() {
|
||||
override fun onResult(proxy: String?, delay: Long) {
|
||||
if ( proxy == null ) {
|
||||
if (proxy == null) {
|
||||
(adapter.elements[position] as ListProxy.ListProxyHeader).urlTest = false
|
||||
|
||||
runOnUiThread {
|
||||
@@ -177,6 +177,7 @@ class ProxyActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
override fun onErrorEvent(event: ErrorEvent?) {
|
||||
Snackbar.make(activity_proxies_root, event?.message ?: "Unknown", Snackbar.LENGTH_LONG).show()
|
||||
Snackbar.make(activity_proxies_root, event?.message ?: "Unknown", Snackbar.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class SettingApplicationActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
|
||||
if ( !isAdded )
|
||||
if (!isAdded)
|
||||
return false
|
||||
|
||||
when (preference?.key) {
|
||||
@@ -60,8 +60,7 @@ class SettingApplicationActivity : BaseActivity() {
|
||||
thread {
|
||||
try {
|
||||
setBootCompleteReceiverEnabled(enabled)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
} catch (e: Exception) {
|
||||
Log.w("Set boot complete failure", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,8 @@ import android.content.IntentFilter
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import com.github.kr328.clash.core.event.ProcessEvent
|
||||
import com.github.kr328.clash.core.event.ProfileReloadEvent
|
||||
import com.github.kr328.clash.service.ClashService
|
||||
import com.github.kr328.clash.service.Constants
|
||||
import com.github.kr328.clash.service.IClashEventObserver
|
||||
import com.github.kr328.clash.service.IClashService
|
||||
import com.github.kr328.clash.service.data.ClashProfileEntity
|
||||
import com.github.kr328.clash.utils.ServiceUtils
|
||||
@@ -41,7 +39,7 @@ class TileService : TileService() {
|
||||
}
|
||||
|
||||
private fun refreshStatus() {
|
||||
if ( qsTile == null )
|
||||
if (qsTile == null)
|
||||
return
|
||||
|
||||
val current = getCurrentStatus()
|
||||
@@ -86,11 +84,14 @@ class TileService : TileService() {
|
||||
|
||||
private fun getCurrentStatus(): Pair<ProcessEvent, ClashProfileEntity?> {
|
||||
val service =
|
||||
IClashService.Stub.asInterface(clashStatusReceiver
|
||||
.peekService(this, Intent(this, ClashService::class.java)))
|
||||
IClashService.Stub.asInterface(
|
||||
clashStatusReceiver
|
||||
.peekService(this, Intent(this, ClashService::class.java))
|
||||
)
|
||||
|
||||
return runCatching {
|
||||
(service?.currentProcessStatus ?: ProcessEvent.STOPPED) to service?.profileService?.queryActiveProfile()
|
||||
(service?.currentProcessStatus
|
||||
?: ProcessEvent.STOPPED) to service?.profileService?.queryActiveProfile()
|
||||
}.getOrNull() ?: ProcessEvent.STOPPED to null
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,12 @@ class FormAdapter(
|
||||
return elements[position].javaClass.hashCode()
|
||||
}
|
||||
|
||||
private fun showTextEditDialog(initial: String, title: String, hint: String, callback: (String) -> Unit) {
|
||||
private fun showTextEditDialog(
|
||||
initial: String,
|
||||
title: String,
|
||||
hint: String,
|
||||
callback: (String) -> Unit
|
||||
) {
|
||||
MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(title)
|
||||
.setView(R.layout.dialog_text_edit)
|
||||
|
||||
@@ -12,8 +12,10 @@ import com.github.kr328.clash.core.event.LogEvent
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class LogAdapter(private val content: Context,
|
||||
private val buffer: CircularArray<LogEvent>) : RecyclerView.Adapter<LogAdapter.Holder>() {
|
||||
class LogAdapter(
|
||||
private val content: Context,
|
||||
private val buffer: CircularArray<LogEvent>
|
||||
) : RecyclerView.Adapter<LogAdapter.Holder>() {
|
||||
private val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
|
||||
|
||||
class Holder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
@@ -23,8 +25,10 @@ class LogAdapter(private val content: Context,
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
|
||||
return Holder(LayoutInflater.from(content)
|
||||
.inflate(R.layout.adapter_log, parent, false))
|
||||
return Holder(
|
||||
LayoutInflater.from(content)
|
||||
.inflate(R.layout.adapter_log, parent, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
|
||||
@@ -11,11 +11,13 @@ import com.github.kr328.clash.view.RadioFatItem
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class ProfileAdapter(private val context: Context,
|
||||
private val onClick: (ClashProfileEntity) -> Unit,
|
||||
private val onOperateClick: (ClashProfileEntity) -> Unit,
|
||||
private val onLongClicked: (View,ClashProfileEntity) -> Unit,
|
||||
private val onNewProfile: () -> Unit) :
|
||||
class ProfileAdapter(
|
||||
private val context: Context,
|
||||
private val onClick: (ClashProfileEntity) -> Unit,
|
||||
private val onOperateClick: (ClashProfileEntity) -> Unit,
|
||||
private val onLongClicked: (View, ClashProfileEntity) -> Unit,
|
||||
private val onNewProfile: () -> Unit
|
||||
) :
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
var profiles: Array<ClashProfileEntity> = emptyArray()
|
||||
|
||||
@@ -23,7 +25,7 @@ class ProfileAdapter(private val context: Context,
|
||||
class NewProfileHolder(val view: FatItem) : RecyclerView.ViewHolder(view)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
if ( viewType == 0 ) {
|
||||
if (viewType == 0) {
|
||||
return NewProfileHolder(FatItem(context).apply {
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -47,7 +49,7 @@ class ProfileAdapter(private val context: Context,
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(raw: RecyclerView.ViewHolder, position: Int) {
|
||||
if ( position == profiles.size ) {
|
||||
if (position == profiles.size) {
|
||||
val holder = raw as NewProfileHolder
|
||||
|
||||
holder.view.icon = context.getDrawable(R.drawable.ic_new_profile)
|
||||
@@ -80,9 +82,10 @@ class ProfileAdapter(private val context: Context,
|
||||
}
|
||||
val now = Calendar.getInstance()
|
||||
|
||||
val formatter = if ( profileUpdateDate.get(Calendar.YEAR) == now.get(Calendar.YEAR) &&
|
||||
val formatter = if (profileUpdateDate.get(Calendar.YEAR) == now.get(Calendar.YEAR) &&
|
||||
profileUpdateDate.get(Calendar.MONTH) == now.get(Calendar.MONTH) &&
|
||||
profileUpdateDate.get(Calendar.DAY_OF_MONTH) == now.get(Calendar.DAY_OF_MONTH) )
|
||||
profileUpdateDate.get(Calendar.DAY_OF_MONTH) == now.get(Calendar.DAY_OF_MONTH)
|
||||
)
|
||||
SimpleDateFormat("HH:mm:ss", Locale.getDefault())
|
||||
else
|
||||
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
@@ -90,19 +93,23 @@ class ProfileAdapter(private val context: Context,
|
||||
when {
|
||||
ClashProfileEntity.isFileToken(current.token) -> {
|
||||
holder.view.operation = context.getDrawable(R.drawable.ic_edit)
|
||||
holder.view.summary = context.getString(R.string.clash_profile_item_summary_file,
|
||||
formatter.format(profileUpdateDate.time))
|
||||
holder.view.summary = context.getString(
|
||||
R.string.clash_profile_item_summary_file,
|
||||
formatter.format(profileUpdateDate.time)
|
||||
)
|
||||
}
|
||||
ClashProfileEntity.isUrlToken(current.token) -> {
|
||||
holder.view.operation = context.getDrawable(R.drawable.ic_sync)
|
||||
holder.view.summary = context.getString(R.string.clash_profile_item_summary_url,
|
||||
formatter.format(profileUpdateDate.time))
|
||||
holder.view.summary = context.getString(
|
||||
R.string.clash_profile_item_summary_url,
|
||||
formatter.format(profileUpdateDate.time)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if ( position == profiles.size )
|
||||
return if (position == profiles.size)
|
||||
0
|
||||
else
|
||||
1
|
||||
|
||||
@@ -13,9 +13,11 @@ import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.model.ListProxy
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
|
||||
class ProxyAdapter(private val context: Context,
|
||||
private val onSelect: (String, String) -> Unit,
|
||||
private val onUrlTest: (Int, Int) -> Unit) :
|
||||
class ProxyAdapter(
|
||||
private val context: Context,
|
||||
private val onSelect: (String, String) -> Unit,
|
||||
private val onUrlTest: (Int, Int) -> Unit
|
||||
) :
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
var elements: List<ListProxy> = emptyList()
|
||||
var clickable: Boolean = false
|
||||
@@ -141,7 +143,7 @@ class ProxyAdapter(private val context: Context,
|
||||
holder.test.visibility =
|
||||
if (current.type == Proxy.Type.SELECT) View.VISIBLE else View.GONE
|
||||
holder.test.setOnClickListener {
|
||||
if ( current.urlTest )
|
||||
if (current.urlTest)
|
||||
return@setOnClickListener
|
||||
|
||||
val indexed = elements.withIndex()
|
||||
|
||||
@@ -5,7 +5,12 @@ import kotlinx.serialization.*
|
||||
import kotlinx.serialization.internal.StringDescriptor
|
||||
|
||||
@Serializable(ClashRule.Serializer::class)
|
||||
data class ClashRule(val matcher: Matcher, val pattern: String, val target: String, val extras: List<String>) {
|
||||
data class ClashRule(
|
||||
val matcher: Matcher,
|
||||
val pattern: String,
|
||||
val target: String,
|
||||
val extras: List<String>
|
||||
) {
|
||||
enum class Matcher {
|
||||
DOMAIN_SUFFIX,
|
||||
DOMAIN_KEYWORD,
|
||||
@@ -76,7 +81,12 @@ data class ClashRule(val matcher: Matcher, val pattern: String, val target: Stri
|
||||
ClashRule(Matcher.fromString(rule[0]), rule[1], rule[2], emptyList())
|
||||
}
|
||||
else -> {
|
||||
ClashRule(Matcher.fromString(rule[0]), rule[1], rule[2], rule.subList(3, rule.size))
|
||||
ClashRule(
|
||||
Matcher.fromString(rule[0]),
|
||||
rule[1],
|
||||
rule[2],
|
||||
rule.subList(3, rule.size)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +95,11 @@ data class ClashRule(val matcher: Matcher, val pattern: String, val target: Stri
|
||||
if (obj.matcher == Matcher.MATCH) {
|
||||
encoder.encodeString("${obj.matcher},${obj.target}")
|
||||
} else {
|
||||
encoder.encodeString("${obj.matcher},${obj.pattern},${obj.target},${obj.extras.joinToString(",")}")
|
||||
encoder.encodeString(
|
||||
"${obj.matcher},${obj.pattern},${obj.target},${obj.extras.joinToString(
|
||||
","
|
||||
)}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,13 @@ package com.github.kr328.clash.model
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
|
||||
interface ListProxy {
|
||||
data class ListProxyHeader(val name: String, val type: Proxy.Type, val now: String, var nowIndex: Int, var urlTest: Boolean = false) :
|
||||
data class ListProxyHeader(
|
||||
val name: String,
|
||||
val type: Proxy.Type,
|
||||
val now: String,
|
||||
var nowIndex: Int,
|
||||
var urlTest: Boolean = false
|
||||
) :
|
||||
ListProxy
|
||||
|
||||
data class ListProxyItem(
|
||||
|
||||
@@ -19,7 +19,7 @@ object ServiceUtils {
|
||||
MainApplication.PROXY_MODE_VPN -> {
|
||||
val prepare = VpnService.prepare(context)
|
||||
|
||||
if ( prepare != null )
|
||||
if (prepare != null)
|
||||
return prepare
|
||||
|
||||
context.startService(Intent(context, TunService::class.java))
|
||||
|
||||
@@ -10,7 +10,7 @@ class MarqueeTextView @JvmOverloads constructor(
|
||||
attributeSet: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0,
|
||||
defStyleRes: Int = 0
|
||||
): TextView(context, attributeSet, defStyleAttr, defStyleRes) {
|
||||
) : TextView(context, attributeSet, defStyleAttr, defStyleRes) {
|
||||
init {
|
||||
ellipsize = TextUtils.TruncateAt.MARQUEE
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user