1 Commits

Author SHA1 Message Date
zarazaex69 1fbb4f2bd3 feat: add copy server button to clipboard 2026-04-22 18:48:34 +03:00
9 changed files with 56 additions and 12 deletions
@@ -73,6 +73,7 @@ object AppConfig {
const val PREF_HEV_TUNNEL_LOGLEVEL = "pref_hev_tunnel_loglevel"
const val PREF_HEV_TUNNEL_RW_TIMEOUT = "pref_hev_tunnel_rw_timeout_v2"
const val PREF_AUTO_SORT_AFTER_TEST = "pref_auto_sort_after_test"
const val PREF_SHOW_COPY_BUTTON = "pref_show_copy_button"
/** Cache keys. */
const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id"
@@ -10,4 +10,6 @@ interface MainAdapterListener :BaseAdapterListener {
fun onShare(guid: String, profile: ProfileItem, position: Int, more: Boolean)
fun onCopyToClipboard(guid: String)
}
@@ -12,6 +12,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.snackbar.Snackbar
import xyz.zarazaex.olc.AppConfig
import xyz.zarazaex.olc.R
import xyz.zarazaex.olc.contracts.MainAdapterListener
@@ -137,9 +138,7 @@ class GroupServerFragment : BaseFragment<FragmentGroupServerBinding>(),
* @param guid The server unique identifier
*/
private fun share2Clipboard(guid: String) {
if (AngConfigManager.share2Clipboard(ownerActivity, guid) == 0) {
ownerActivity.toastSuccess(R.string.toast_success)
} else {
if (AngConfigManager.share2Clipboard(ownerActivity, guid) != 0) {
ownerActivity.toastError(R.string.toast_failure)
}
}
@@ -264,6 +263,10 @@ class GroupServerFragment : BaseFragment<FragmentGroupServerBinding>(),
setSelectServer(guid)
}
override fun onCopyToClipboard(guid: String) {
share2Clipboard(guid)
}
override fun onShare(guid: String, profile: ProfileItem, position: Int, more: Boolean) {
val isCustom = profile.configType == EConfigType.CUSTOM || profile.configType == EConfigType.POLICYGROUP
@@ -33,6 +33,8 @@ class MainRecyclerAdapter(
private val doubleColumnDisplay =
MmkvManager.decodeSettingsBool(AppConfig.PREF_DOUBLE_COLUMN_DISPLAY, false)
private val showCopyButton =
MmkvManager.decodeSettingsBool(AppConfig.PREF_SHOW_COPY_BUTTON, false)
private var data: MutableList<ServersCache> = mutableListOf()
private var recyclerView: RecyclerView? = null
@@ -200,6 +202,11 @@ class MainRecyclerAdapter(
mainViewModel.reloadServerList()
}
holder.itemMainBinding.ivCopy.visibility = if (showCopyButton) View.VISIBLE else View.GONE
holder.itemMainBinding.ivCopy.setOnClickListener {
adapterListener?.onCopyToClipboard(guid)
}
holder.itemMainBinding.infoContainer.setOnClickListener {
adapterListener?.onSelectServer(guid)
}
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="@android:color/white"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z" />
</vector>
@@ -99,16 +99,35 @@
</LinearLayout>
<ImageView
android:id="@+id/iv_favorite"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_spacing_dp8"
android:src="@drawable/ic_star_empty" />
android:orientation="vertical"
android:gravity="end">
<ImageView
android:id="@+id/iv_favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_spacing_dp8"
android:src="@drawable/ic_star_empty" />
<ImageView
android:id="@+id/iv_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_spacing_dp8"
android:visibility="gone"
app:srcCompat="@drawable/ic_copy"
app:tint="?attr/colorAccent" />
</LinearLayout>
</LinearLayout>
@@ -236,6 +236,9 @@
<string name="title_pref_group_all_display">Общая вкладка групп</string>
<string name="summary_pref_group_all_display">Показывать дополнительную вкладку со всеми профилями групп</string>
<string name="title_pref_show_copy_button">Кнопка копирования</string>
<string name="summary_pref_show_copy_button">Показывать кнопку копирования конфигурации сервера в буфер обмена</string>
<!-- AboutActivity -->
<string name="title_pref_feedback">Обратная связь</string>
<string name="summary_pref_feedback">Предложить улучшение или сообщить об ошибке на GitHub</string>
@@ -160,6 +160,9 @@
<string name="title_pref_auto_sort_after_test">Auto sort after testing</string>
<string name="summary_pref_auto_sort_after_test">Test results may not be accurate;</string>
<string name="title_pref_show_copy_button">Show copy button</string>
<string name="summary_pref_show_copy_button">Show button to copy server configuration to clipboard</string>
<string name="title_mux_settings">Mux Settings</string>
<string name="title_pref_mux_enabled">Enable Mux</string>
<string name="summary_pref_mux_enabled">Faster, but it may cause unstable connectivity\nCustomize how to handle TCP, UDP and QUIC below</string>
@@ -28,6 +28,12 @@
android:summary="@string/summary_pref_group_all_display"
android:title="@string/title_pref_group_all_display" />
<CheckBoxPreference
android:key="pref_show_copy_button"
android:defaultValue="false"
android:summary="@string/summary_pref_show_copy_button"
android:title="@string/title_pref_show_copy_button" />
<ListPreference
android:defaultValue="auto"
android:entries="@array/language_select"