6.7.0 - Alpha12 - 插件中心 M1 - 插件中心列表渲染支持本地发现与索引读取; 启动器快捷方式添加 "插件" 选项

This commit is contained in:
SuperMonster003
2025-11-28 14:38:36 +08:00
parent a26ecba492
commit 1fcfd7233f
55 changed files with 1379 additions and 173 deletions

View File

@@ -35,9 +35,15 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission
android:name="android.permission.READ_MEDIA_IMAGES"
tools:ignore="SelectedPhotoAccess" />
<uses-permission
android:name="android.permission.READ_MEDIA_VIDEO"
tools:ignore="SelectedPhotoAccess" />
<uses-permission
android:name="android.permission.READ_MEDIA_AUDIO"
tools:ignore="SelectedPhotoAccess" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
@@ -322,8 +328,7 @@
android:exported="false"
android:launchMode="singleTask"
android:taskAffinity="${applicationId}.crash_report"
android:excludeFromRecents="true">
</activity>
android:excludeFromRecents="true" />
<activity
android:name="org.autojs.autojs.external.tasker.TaskerScriptEditActivity"
@@ -626,6 +631,10 @@
android:name="org.autojs.autojs.theme.app.ColorItemsActivity"
android:theme="@style/MtAppTheme.FullScreen" />
<activity
android:name="org.autojs.autojs.core.plugin.center.PluginCenterActivity"
android:theme="@style/AppTheme.Settings" />
<activity
android:name="org.autojs.autojs.execution.ScriptExecuteActivity"
android:configChanges="orientation|keyboardHidden|screenSize|locale"

View File

@@ -0,0 +1,63 @@
package org.autojs.autojs.core.plugin.center
import android.content.Context
import android.graphics.drawable.Drawable
import androidx.core.content.pm.PackageInfoCompat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.autojs.autojs.core.plugin.ocr.PaddleOcrPluginHost
import org.autojs.autojs6.R
import org.autojs.plugin.paddle.ocr.PluginInfo
/**
* Local installed plugin discovery (based on existing PaddleOcrPluginHost.discover).
*
* zh-CN: 本地已安装插件发现 (基于现有的 PaddleOcrPluginHost.discover).
*/
class InstalledPluginRepository {
data class InstalledPlugin(
val packageName: String,
val title: String,
val description: String?,
val author: String?,
val versionName: String,
val versionCode: Long?,
val installTime: Long?,
val updateTime: Long?,
val icon: Drawable?,
val pluginInfo: PluginInfo?,
)
suspend fun discoverInstalled(context: Context): List<InstalledPlugin> = withContext(Dispatchers.IO) {
val pm = context.packageManager
val discovered = runCatching { PaddleOcrPluginHost.discover(context) }.getOrElse { emptyList() }
discovered.map { d ->
val serviceInfo = d.serviceInfo
val packageName = serviceInfo.packageName
val appInfo = runCatching { pm.getApplicationInfo(packageName, 0) }.getOrNull()
val appLabel = appInfo?.loadLabel(pm)?.toString()
val icon = appInfo?.loadIcon(pm)
val pkgInfo = runCatching { pm.getPackageInfo(packageName, 0) }.getOrNull()
val versionName = pkgInfo?.versionName ?: d.pluginInfo?.versionName ?: context.getString(R.string.text_unknown)
val versionCode = pkgInfo?.let { PackageInfoCompat.getLongVersionCode(it) } ?: d.pluginInfo?.versionCode
val firstInstallTime = pkgInfo?.firstInstallTime
val lastUpdateTime = pkgInfo?.lastUpdateTime
InstalledPlugin(
packageName = packageName,
title = d.pluginInfo?.name ?: appLabel ?: packageName,
description = d.pluginInfo?.description,
author = d.pluginInfo?.author,
versionName = versionName,
versionCode = versionCode,
installTime = firstInstallTime,
updateTime = lastUpdateTime,
icon = icon,
pluginInfo = d.pluginInfo,
)
}
}
}

View File

@@ -0,0 +1,41 @@
package org.autojs.autojs.core.plugin.center
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.ActivityPluginCenterBinding
@SuppressLint("NotifyDataSetChanged")
class PluginCenterActivity : BaseActivity() {
private lateinit var binding: ActivityPluginCenterBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPluginCenterBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
supportFragmentManager
.beginTransaction()
.replace(R.id.fragment_plugin_center, PluginCenterFragment())
.commit()
setToolbarAsBack(R.string.text_plugin_center)
}
companion object {
fun startActivity(context: Context) {
Intent(context, PluginCenterActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.let { context.startActivity(it) }
}
}
}

View File

@@ -0,0 +1,58 @@
package org.autojs.autojs.core.plugin.center
import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.FragmentPluginCenterBinding
class PluginCenterFragment : Fragment(R.layout.fragment_plugin_center) {
private var _binding: FragmentPluginCenterBinding? = null
private val binding get() = _binding!!
private val vm: PluginCenterViewModel by viewModels()
private lateinit var adapter: PluginCenterItemAdapter
private lateinit var context: Context
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentPluginCenterBinding.bind(view)
val context = requireContext().also { context = it }
binding.pluginCenterRecyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = PluginCenterItemAdapter().also { this@PluginCenterFragment.adapter = it }
addItemDecoration(DividerItemDecoration(context, VERTICAL))
excludePaddingClippableViewFromBottomNavigationBar()
}
// Load data.
// zh-CN: 加载数据.
vm.load(context)
// Subscribe data updates.
// zh-CN: 订阅数据更新.
viewLifecycleOwner.lifecycleScope.launch {
vm.items.collectLatest { list ->
adapter.updateData(list)
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,18 @@
package org.autojs.autojs.core.plugin.center
import android.graphics.drawable.Drawable
data class PluginCenterItem(
val packageName: String,
val title: String,
val description: String,
val author: String? = null,
val collaborators: List<String> = emptyList(),
val versionName: String,
val versionCode: Long? = null,
val versionDate: String? = null,
val isEnabled: Boolean = true,
val isUpdatable: Boolean = false,
val icon: Drawable? = null,
val settings: PluginCenterItemSettings? = null,
)

View File

@@ -0,0 +1,32 @@
package org.autojs.autojs.core.plugin.center
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.autojs.autojs6.databinding.PluginCenterRecyclerViewItemBinding
@SuppressLint("NotifyDataSetChanged")
class PluginCenterItemAdapter : RecyclerView.Adapter<PluginCenterItemViewHolder>() {
internal var items = emptyList<PluginCenterItem>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PluginCenterItemViewHolder {
val binding = PluginCenterRecyclerViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return PluginCenterItemViewHolder(binding)
}
override fun onBindViewHolder(holder: PluginCenterItemViewHolder, position: Int) {
holder.bind(items[position])
}
override fun getItemCount() = items.size
fun items() = items
fun updateData(newItems: List<PluginCenterItem>) {
items = newItems
notifyDataSetChanged()
}
}

View File

@@ -0,0 +1,5 @@
package org.autojs.autojs.core.plugin.center
data class PluginCenterItemSettings(
val title: String? = null,
)

View File

@@ -0,0 +1,187 @@
package org.autojs.autojs.core.plugin.center
import android.content.res.ColorStateList
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.PorterDuff
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import androidx.recyclerview.widget.RecyclerView
import de.hdodenhof.circleimageview.CircleImageView
import org.autojs.autojs.theme.ThemeColorManager
import org.autojs.autojs.util.ColorUtils
import org.autojs.autojs.util.ViewUtils
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.PluginCenterRecyclerViewItemBinding
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
class PluginCenterItemViewHolder(itemViewBinding: PluginCenterRecyclerViewItemBinding) : RecyclerView.ViewHolder(itemViewBinding.root) {
private val context = itemViewBinding.root.context
private val themeColor
get() = ThemeColorManager.colorPrimary
private val adjustedTextContrastColor
get() = ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), themeColor, 3.2)
private val adjustedImageContrastColor
get() = ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), themeColor, 2.3)
private val iconView: CircleImageView = itemViewBinding.icon
private val titleView = itemViewBinding.title
private val versionInfoView = itemViewBinding.versionInfo
private val authorView = itemViewBinding.author
private val descriptionView = itemViewBinding.description
private val switchView = itemViewBinding.sw
private val updatableBadgeView = itemViewBinding.updatableBadge
private val updatableBadgeTextView = itemViewBinding.updatableBadgeText
private val versionInfoForUpdateView = itemViewBinding.versionInfoForUpdate
private val btnDeleteView = itemViewBinding.btnDelete
private val btnUpdateView = itemViewBinding.btnUpdate
private val btnSettingsView = itemViewBinding.btnSettings
private val btnDetailsView = itemViewBinding.btnDetails
fun bind(item: PluginCenterItem) {
item.icon?.let { iconView.setImageDrawable(it) } ?: AppCompatResources.getDrawable(
iconView.context,
R.drawable.ic_plugin_center_default
)?.mutate()?.let { d ->
DrawableCompat.setTint(d, adjustedImageContrastColor)
DrawableCompat.setTintMode(d, PorterDuff.Mode.SRC_IN)
iconView.setImageDrawable(d)
} ?: iconView.setImageResource(R.mipmap.ic_app_shortcut_plugin_center_adaptive_round)
switchView.isChecked = item.isEnabled
titleView.text = item.title
versionInfoView.text = formatVersionInfo(item.versionName, item.versionCode, item.versionDate)
authorView.text = item.author
descriptionView.text = item.description
btnDeleteView.setButtonState(true) {
ViewUtils.showToast(context, R.string.text_under_development)
}
if (item.isUpdatable) {
updatableBadgeView.isVisible = true
versionInfoForUpdateView.isVisible = true
versionInfoForUpdateView.text = formatVersionInfo(item.versionName, item.versionCode?.let { it + 16 }, item.versionDate?.let {
DateTime.parse(it).plusDays(3).toString("yyyy-MM-dd")
})
btnUpdateView.setButtonState(true) {
ViewUtils.showToast(context, R.string.text_under_development)
}
} else {
updatableBadgeView.isVisible = false
versionInfoForUpdateView.isVisible = false
btnUpdateView.setButtonState(false) {
ViewUtils.showToast(context, R.string.text_unavailable)
}
}
if (item.settings != null) {
btnSettingsView.setButtonState(true) {
ViewUtils.showToast(context, R.string.text_under_development)
}
} else {
btnSettingsView.setButtonState(false) {
ViewUtils.showToast(context, R.string.text_unavailable)
}
}
btnDetailsView.setButtonState(true) {
ViewUtils.showToast(context, R.string.text_under_development)
}
applyUiBySwitch(switchView.isChecked, item)
switchView.setOnCheckedChangeListener { _, isChecked ->
applyUiBySwitch(isChecked, item)
}
}
private fun formatVersionInfo(versionName: String, versionCode: Long?, versionDate: String?): String {
val code = versionCode?.takeIf { it > 0 }
val date = versionDate?.runCatching {
DateTimeFormat.forPattern("yyyy-MM-dd").print(DateTime.parse(this))
}?.getOrNull()
return buildString {
append(versionName)
code?.let { append(" ($it)") }
date?.let { append(" | $it") }
}
}
private fun LinearLayout.setButtonState(enabled: Boolean, onClickListener: View.OnClickListener) {
isEnabled = enabled
this.setOnClickListener(onClickListener)
}
private fun applyUiBySwitch(isOn: Boolean, item: PluginCenterItem) {
val colorPrimary = context.getColor(R.color.text_color_primary)
val colorPrimaryA50 = context.getColor(R.color.text_color_primary_alpha_50)
val colorPrimaryA30 = context.getColor(R.color.text_color_primary_alpha_30)
val colorPrimaryA20 = context.getColor(R.color.text_color_primary_alpha_20)
btnDeleteView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
if (btnUpdateView.isEnabled) {
if (isOn) {
btnUpdateView.setActionColors(iconColor = adjustedImageContrastColor, textColor = adjustedTextContrastColor)
} else {
btnUpdateView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
}
} else {
btnUpdateView.setActionColors(iconColor = colorPrimaryA20, textColor = colorPrimaryA30)
}
if (item.settings == null) {
btnSettingsView.setActionColors(iconColor = colorPrimaryA20, textColor = colorPrimaryA30)
} else {
btnSettingsView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
}
btnDetailsView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
if (isOn) {
versionInfoForUpdateView.setTextColor(adjustedTextContrastColor)
updatableBadgeTextView.setTextColor(adjustedTextContrastColor)
} else {
versionInfoForUpdateView.setTextColor(colorPrimary)
updatableBadgeTextView.setTextColor(colorPrimary)
}
if (isOn) {
iconView.colorFilter = null
} else {
// Construct the desaturation matrix.
// zh-CN: 构造灰度矩阵.
val desaturate = ColorMatrix().apply { setSaturation(0f) }
// Construct the alpha scaling matrix.
// zh-CN: 构造透明度缩放矩阵.
val alphaMatrix = ColorMatrix().apply { setScale(1f, 1f, 1f, 0.5f) }
// Concatenate: first desaturate, then apply alpha.
// zh-CN: 叠加: 先灰度, 再透明度.
desaturate.postConcat(alphaMatrix)
iconView.colorFilter = ColorMatrixColorFilter(desaturate)
}
}
private fun LinearLayout.setActionColors(iconColor: Int, textColor: Int) {
val imageView = getChildAtOrNull(0) as? ImageView
val textView = getChildAtOrNull(1) as? TextView
imageView?.let { ImageViewCompat.setImageTintList(it, ColorStateList.valueOf(iconColor)) }
textView?.setTextColor(textColor)
}
private fun LinearLayout.getChildAtOrNull(index: Int) = if (index in 0 until childCount) getChildAt(index) else null
}

View File

@@ -0,0 +1,82 @@
package org.autojs.autojs.core.plugin.center
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import org.autojs.autojs6.R
/**
* Loads both index plugins and locally installed plugins,
* merging them into a PluginCenterItem list.
*
* zh-CN: 统一加载索引插件与本地已安装插件, 合并为 PluginCenterItem 列表.
*/
class PluginCenterViewModel : ViewModel() {
private val indexRepo = PluginIndexRepository()
private val installedRepo = InstalledPluginRepository()
private val _items = MutableStateFlow<List<PluginCenterItem>>(emptyList())
val items: StateFlow<List<PluginCenterItem>> = _items
fun load(context: Context) {
viewModelScope.launch {
val idxDeferred = async { runCatching { indexRepo.fetchOfficialIndex(context) }.getOrElse { emptyList() } }
val insDeferred = async { runCatching { installedRepo.discoverInstalled(context) }.getOrElse { emptyList() } }
val indexEntries = idxDeferred.await()
val installed = insDeferred.await()
val installedByPkg = installed.associateBy { it.packageName }
// 1. Use index to drive UI first (ensuring "installable but not installed" items are displayed).
// 1. [ zh-CN ] 优先用索引驱动 UI (确保 "未安装但可安装" 的项也能显示).
val fromIndex = indexEntries.map { e ->
val local = installedByPkg[e.packageName]
toPluginCenterItem(context, index = e, local = local)
}
// 2. Add items that "exist locally but not in index" (third-party or not indexed yet).
// 2. [ zh-CN ] 补充 "本地存在但索引里暂时没有" 的项 (第三方或暂未入索引).
val extraLocals = installed
.filter { ins -> indexEntries.none { it.packageName == ins.packageName } }
.map { local -> toPluginCenterItem(context, index = null, local = local) }
_items.value = fromIndex + extraLocals
}
}
private fun toPluginCenterItem(context: Context, index: PluginIndexEntry?, local: InstalledPluginRepository.InstalledPlugin?): PluginCenterItem {
val packageName = local?.packageName ?: index?.packageName.orEmpty()
val title = local?.title ?: index?.title ?: packageName
val description = local?.description ?: index?.description.orEmpty()
val author = local?.author ?: index?.author
val collaborators = index?.collaborators ?: emptyList()
val versionName = local?.versionName ?: index?.versionName ?: context.getString(R.string.text_unknown)
val localCode = local?.versionCode
val indexCode = index?.versionCode
val isInstalled = local != null
val isUpdatable = isInstalled && (indexCode != null && indexCode > (localCode ?: -1))
return PluginCenterItem(
packageName = packageName,
title = title,
description = description,
author = author,
collaborators = collaborators,
versionName = versionName,
versionCode = localCode ?: indexCode,
versionDate = index?.versionDate, // M1: 显示索引日期; 仅本地项时可为空
isEnabled = true, // M1: 先统一 true, M2 再接入启用状态持久化
isUpdatable = isUpdatable,
icon = local?.icon, // 已安装优先用应用图标; 未安装走默认占位图
settings = null, // M1 暂不接入单插件设置入口
)
}
}

View File

@@ -0,0 +1,27 @@
package org.autojs.autojs.core.plugin.center
import android.net.Uri
data class PluginIndexEntry(
val packageName: String,
val iconUrl: Uri? = null,
val title: String,
val description: String,
val author: String? = null,
val collaborators: List<String> = emptyList(),
/** @sample "paddle-ocr" */
val engine: String? = null,
/** @sample "v5" */
val variant: String? = null,
/** @sample "paddle-ocr-v5" */
val engineId: String? = null,
val versionName: String,
val versionCode: Long? = null,
val versionDate: String? = null,
val tags: List<String> = emptyList(),
)

View File

@@ -0,0 +1,30 @@
package org.autojs.autojs.core.plugin.center
import android.content.Context
/**
* 官方插件索引仓库 (M1: 内置静态; M2 再接入网络/ETag/缓存).
*/
class PluginIndexRepository {
suspend fun fetchOfficialIndex(context: Context): List<PluginIndexEntry> {
// M1 先预置 1 条官方样例 "Paddle OCR (PP-OCRv5)", 便于与本地已安装合并显示.
return listOf(
PluginIndexEntry(
packageName = "io.github.supermonster003.autojs6.plugin.paddleocr.v5",
title = "Paddle OCR (PP-OCRv5)",
description = "百度飞桨光学字符识别插件",
author = "SuperMonster003",
collaborators = emptyList(),
versionName = "0.1.0",
versionCode = 17L,
versionDate = "2025-11-21",
iconUrl = null, // M1 暂不拉网图标, 使用应用图标或默认图标.
tags = listOf("official", "ocr", "paddle", "v5"),
engine = "paddle-ocr",
variant = "v5",
engineId = "paddle-ocr-v5",
),
)
}
}

View File

@@ -2,7 +2,6 @@ package org.autojs.autojs.ui.main.drawer
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -15,6 +14,7 @@ import org.autojs.autojs.app.tool.FloatingButtonTool
import org.autojs.autojs.app.tool.JsonSocketClientTool
import org.autojs.autojs.app.tool.JsonSocketServerTool
import org.autojs.autojs.core.accessibility.AccessibilityTool
import org.autojs.autojs.core.plugin.center.PluginCenterActivity
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.permission.DisplayOverOtherAppsPermission
import org.autojs.autojs.permission.IgnoreBatteryOptimizationsPermission
@@ -410,12 +410,8 @@ open class DrawerFragment : Fragment() {
}
private fun setupListeners() {
binding.settings.setOnClickListener { view ->
startActivity(
Intent(view.context, PreferencesActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
}
binding.settings.setOnClickListener { PreferencesActivity.launch(it.context) }
binding.pluginCenter.setOnClickListener { PluginCenterActivity.startActivity(it.context) }
binding.restart.setOnClickListener { restart(mActivity, mActivity::beforeExit) }
binding.exit.setOnClickListener { exit(mActivity, mActivity::beforeExit) }
}

View File

@@ -5,6 +5,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.core.content.pm.ShortcutManagerCompat
import com.afollestad.materialdialogs.MaterialDialog
import org.autojs.autojs.core.plugin.center.PluginCenterActivity
import org.autojs.autojs.theme.preference.MaterialPreference
import org.autojs.autojs.ui.doc.DocumentationActivity
import org.autojs.autojs.ui.log.LogActivity
@@ -21,43 +22,60 @@ class LauncherShortcutsPreference : MaterialPreference {
val binding = SelectLauncherShortcutBinding.inflate(LayoutInflater.from(prefContext))
MaterialDialog.Builder(prefContext)
.customView(binding.root, true)
val dialog = MaterialDialog.Builder(prefContext)
.customView(binding.root, false)
.build()
.also { dialog ->
binding.launcherShortcutSettings.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_settings,
PreferencesActivity::class.java.name,
R.string.text_app_shortcut_settings_long_label,
R.string.text_app_shortcut_settings_short_label,
R.mipmap.ic_app_shortcut_settings_adaptive,
).also { dialog.dismiss() }
}
binding.launcherShortcutDocs.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_docs,
DocumentationActivity::class.java.name,
R.string.text_app_shortcut_docs_long_label,
R.string.text_app_shortcut_docs_short_label,
R.mipmap.ic_app_shortcut_docs_adaptive,
).also { dialog.dismiss() }
}
dialog.window?.apply {
setBackgroundDrawable(null)
setDimAmount(0.64f)
}
binding.launcherShortcutLog.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_log,
LogActivity::class.java.name,
R.string.text_app_shortcut_log_long_label,
R.string.text_app_shortcut_log_short_label,
R.mipmap.ic_app_shortcut_log_adaptive,
).also { dialog.dismiss() }
}
}
binding.launcherShortcutSettings.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_settings,
PreferencesActivity::class.java.name,
R.string.text_app_shortcut_settings_long_label,
R.string.text_app_shortcut_settings_short_label,
R.mipmap.ic_app_shortcut_settings_adaptive,
).also { dialog.dismiss() }
}
binding.launcherShortcutDocs.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_docs,
DocumentationActivity::class.java.name,
R.string.text_app_shortcut_docs_long_label,
R.string.text_app_shortcut_docs_short_label,
R.mipmap.ic_app_shortcut_docs_adaptive,
).also { dialog.dismiss() }
}
binding.launcherShortcutLog.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_log,
LogActivity::class.java.name,
R.string.text_app_shortcut_log_long_label,
R.string.text_app_shortcut_log_short_label,
R.mipmap.ic_app_shortcut_log_adaptive,
).also { dialog.dismiss() }
}
binding.launcherShortcutPluginCenter.setOnClickListener {
ShortcutUtils.requestPinShortcut(
prefContext,
R.string.id_launcher_shortcut_plugin_center,
PluginCenterActivity::class.java.name,
R.string.text_app_shortcut_plugin_center_long_label,
R.string.text_app_shortcut_plugin_center_short_label,
R.mipmap.ic_app_shortcut_plugin_center_adaptive,
).also { dialog.dismiss() }
}
return@lazy dialog
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,23 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="512"
android:viewportHeight="512">
<group
android:pivotX="256"
android:pivotY="256"
android:scaleX="1.05"
android:scaleY="1.05">
<group
android:scaleX="0.704"
android:scaleY="0.704"
android:translateX="69.426075"
android:translateY="82.450966">
<path
android:pathData="m162.27,317.75 l-30.92,30.65 39.62,39.61 31.29,-31.03c69.87,57.6 131.69,-3.38 177.78,-49.48L357.55,285l49.47,-49.45c8.33,-8.33 8.33,-21.98 0,-30.32 -8.34,-8.34 -21.99,-8.33 -30.32,0l-49.46,49.46 -63.1,-63.09 49.46,-49.47c8.34,-8.33 8.34,-21.98 0,-30.31 -8.34,-8.34 -21.98,-8.34 -30.32,0l-49.46,49.46 -21.69,-21.7c-47.36,47.36 -106.64,105.87 -49.86,178.17z"
android:fillColor="#fff"
android:fillType="evenOdd" />
</group>
</group>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,23 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="512"
android:viewportHeight="512">
<group
android:pivotX="256"
android:pivotY="256"
android:scaleX="1.32"
android:scaleY="1.32">
<group
android:scaleX="0.704"
android:scaleY="0.704"
android:translateX="69.426075"
android:translateY="82.450966">
<path
android:pathData="m162.27,317.75 l-30.92,30.65 39.62,39.61 31.29,-31.03c69.87,57.6 131.69,-3.38 177.78,-49.48L357.55,285l49.47,-49.45c8.33,-8.33 8.33,-21.98 0,-30.32 -8.34,-8.34 -21.99,-8.33 -30.32,0l-49.46,49.46 -63.1,-63.09 49.46,-49.47c8.34,-8.33 8.34,-21.98 0,-30.31 -8.34,-8.34 -21.98,-8.34 -30.32,0l-49.46,49.46 -21.69,-21.7c-47.36,47.36 -106.64,105.87 -49.86,178.17z"
android:fillColor="#fff"
android:fillType="evenOdd" />
</group>
</group>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:theme="@style/AppTheme.AppBarOverlay">
<org.autojs.autojs.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:theme="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
tools:title="@string/text_sample_string" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_plugin_center"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -22,100 +22,130 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="2dp"
android:background="?android:divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="41dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:baselineAligned="false">
<LinearLayout
android:id="@+id/settings"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?selectableItemBackground"
android:gravity="center"
android:orientation="horizontal">
android:layout_gravity="center|bottom"
android:orientation="vertical">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="17dp"
android:layout_height="17dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_ali_settings"
android:layout_marginBottom="2dp"
android:src="@drawable/ic_settings"
android:translationY="-0.4dp"
app:tint="?android:textColorPrimary"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="4dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/text_settings"
android:textColor="?android:textColorPrimary"
android:textSize="15sp" />
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/plugin_center"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?selectableItemBackground"
android:layout_gravity="center|bottom"
android:orientation="vertical">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center"
android:layout_marginBottom="2dp"
android:src="@drawable/ic_jigsaw"
android:translationY="-0.6dp"
app:tint="?android:textColorPrimary"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/text_plugins"
android:textColor="?android:textColorPrimary"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/restart"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?selectableItemBackground"
android:gravity="center"
android:orientation="horizontal">
android:layout_gravity="center|bottom"
android:orientation="vertical">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:layout_marginBottom="2dp"
android:src="@drawable/ic_refresh_white_24dp"
android:translationY="1dp"
app:tint="?android:textColorPrimary"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="4dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/text_restart"
android:textColor="?android:textColorPrimary"
android:textSize="15sp" />
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/exit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?selectableItemBackground"
android:gravity="center"
android:orientation="horizontal">
android:layout_gravity="center|bottom"
android:orientation="vertical">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_ali_exit"
android:layout_marginBottom="2dp"
android:translationY="0.8dp"
android:src="@drawable/ic_power_switch"
app:tint="?android:textColorPrimary"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="4dp"
android:textColor="?android:textColorPrimary"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/text_exit"
android:textSize="15sp" />
android:textColor="?android:textColorPrimary"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.ThemeColorRecyclerView
android:id="@+id/plugin_center_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="true"
android:scrollbarDefaultDelayBeforeFade="600"
android:scrollbarFadeDuration="500"
android:scrollbars="vertical" />
</FrameLayout>

View File

@@ -0,0 +1,317 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon"
android:layout_width="@dimen/plugin_center_item_side_length"
android:layout_height="@dimen/plugin_center_item_side_length"
android:layout_gravity="center"
android:src="@drawable/ic_app_shortcut_plugin_center_adaptive_foreground"
app:civ_border_color="@color/plugin_center_item_icon_border"
app:civ_border_width="@dimen/plugin_center_item_icon_border_width"
tools:src="@drawable/ic_plugin_paddle_ocr" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:gravity="center_vertical"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:maxLines="1"
android:textColor="@color/text_color_primary"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/updatable_badge"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="0dp"
tools:text="Paddle OCR (PP-OCRv5)" />
<FrameLayout
android:id="@+id/updatable_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<TextView
android:id="@+id/updatable_badge_text"
android:layout_width="@dimen/plugin_center_item_side_length"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:padding="2sp"
android:textColor="#03A5EF"
android:textSize="12sp"
android:text="@string/text_updatable" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/version_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/text_color_primary"
android:textSize="13sp"
tools:text="v0.1.0 (17) | 2025/11/21" />
<TextView
android:id="@+id/version_info_for_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#03A5EF"
android:textSize="13sp"
android:visibility="gone"
tools:text="v0.1.1 (22) | 2025/11/23"
tools:visibility="visible" />
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/text_color_primary"
android:textSize="13sp"
tools:text="SuperMonster003" />
</LinearLayout>
<FrameLayout
android:layout_width="@dimen/plugin_center_item_side_length"
android:layout_height="match_parent"
android:layout_gravity="center">
<org.autojs.autojs.theme.widget.ThemeColorSwitch
android:id="@+id/sw"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:checked="true"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/text_color_primary_alpha_70"
android:textSize="12sp"
tools:text="百度飞桨光学字符识别插件" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:layout_marginVertical="8dp"
android:background="@color/divider_app_settings_list" />
<LinearLayout
android:id="@+id/ll_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:minWidth="@dimen/plugin_center_item_side_length"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="4dp"
android:contentDescription="@string/text_uninstall"
android:src="@drawable/ic_delete_forever_black_48dp"
app:tint="@color/text_color_primary_alpha_50" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:text="@string/text_uninstall"
android:textColor="@color/text_color_primary"
android:textSize="13sp"
android:translationY="-0.5dp" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="18dp"
android:layout_weight="1" />
<LinearLayout
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:minWidth="@dimen/plugin_center_item_side_length"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?selectableItemBackground"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
tools:backgroundTint="#03A5EF"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="4dp"
android:contentDescription="@string/text_update"
android:src="@drawable/ic_cloud_download_black_48dp"
app:tint="@color/text_color_primary_alpha_20"
tools:tint="#03A5EF" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:text="@string/text_update"
android:textColor="@color/text_color_primary_alpha_30"
android:textSize="13sp"
android:translationY="-0.5dp"
tools:textColor="#03A5EF" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="18dp"
android:layout_weight="1" />
<LinearLayout
android:id="@+id/btn_settings"
android:layout_width="wrap_content"
android:minWidth="@dimen/plugin_center_item_side_length"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="4dp"
android:layout_gravity="center"
android:contentDescription="@string/text_settings"
android:src="@drawable/ic_circular_menu_settings"
app:tint="@color/text_color_primary_alpha_20" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:text="@string/text_settings"
android:textColor="@color/text_color_primary_alpha_30"
android:textSize="13sp"
android:translationY="-0.5dp" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="18dp"
android:layout_weight="1" />
<LinearLayout
android:id="@+id/btn_details"
android:layout_width="wrap_content"
android:minWidth="@dimen/plugin_center_item_side_length"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="4dp"
android:contentDescription="@string/text_details"
android:src="@drawable/ic_info_black_48dp"
app:tint="@color/text_color_primary_alpha_50" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:text="@string/text_details"
android:textColor="@color/text_color_primary"
android:textSize="13sp"
android:translationY="-0.5dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -1,118 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:gravity="center_vertical"
android:layout_gravity="center"
android:paddingVertical="16dp"
android:orientation="vertical">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="?selectableItemBackground"
android:gravity="center_vertical"
android:layout_gravity="center"
android:paddingVertical="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/launcher_shortcut_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
android:layout_weight="1"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<LinearLayout
android:id="@+id/launcher_shortcut_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_settings_adaptive" />
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_settings_adaptive_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_settings_short_label" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/night"
tools:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_settings_short_label" />
</LinearLayout>
<LinearLayout
android:id="@+id/launcher_shortcut_docs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
android:id="@+id/launcher_shortcut_docs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_docs_adaptive" />
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_docs_adaptive_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_docs_short_label" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/night"
tools:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_docs_short_label" />
</LinearLayout>
<LinearLayout
android:id="@+id/launcher_shortcut_log"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
android:id="@+id/launcher_shortcut_log"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_log_adaptive" />
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_log_adaptive_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_log_short_label" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/night"
tools:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_log_short_label" />
</LinearLayout>
<LinearLayout
android:id="@+id/launcher_shortcut_plugin_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginVertical="2dp"
android:clickable="false"
android:focusable="false"
android:src="@mipmap/ic_app_shortcut_plugin_center_adaptive_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:gravity="center"
android:layout_gravity="center|bottom"
android:layout_marginTop="6dp"
android:textColor="@color/night"
tools:textColor="@color/day_night"
android:clickable="false"
android:focusable="false"
android:text="@string/text_app_shortcut_plugin_center_short_label" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/text_click_icon_to_add_launcher_shortcut"
android:textSize="12sp"
android:textColor="@color/night"
tools:textColor="@color/day_night" />
<View
android:layout_height="12dp"
android:layout_width="match_parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/text_click_other_areas_to_exit_selection"
android:textSize="12sp"
android:textColor="@color/night"
tools:textColor="@color/day_night" />
</LinearLayout>
</LinearLayout>

View File

@@ -11,7 +11,7 @@
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search_black_48dp"
android:icon="@drawable/ic_search_smaller_black_48dp"
android:title="@string/text_search"
android:imeOptions="actionSearch"
android:inputType="text"

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_app_shortcut_plugin_center_adaptive_background"/>
<foreground android:drawable="@drawable/ic_app_shortcut_plugin_center_adaptive_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_app_shortcut_plugin_center_adaptive_background"/>
<foreground android:drawable="@drawable/ic_app_shortcut_plugin_center_adaptive_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1079,5 +1079,14 @@
<string name="text_write_secure_settings">اكتب إعدادات الأمان</string>
<string name="text_write_secure_settings_description">إعدادات النظام الآمنة ، التي تحتوي على تفضيلات النظام التي يمكن أن تقرأها التطبيقات ولكن لا يُسمح لها بالكتابة.\nهذه هي لتفضيلات يجب على المستخدم تعديلها بشكل صريح من خلال واجهة المستخدم لتطبيق النظام.\nمع إذن إعدادات النظام الآمن ، يمكن للتطبيقات العادية تعديل الإعدادات الآمنة مباشرة (مثل خدمة إمكانية الوصول).</string>
<string name="text_write_system_settings">كتابة إعدادات النظام</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1074,5 +1074,14 @@
<string name="text_write_secure_settings">Write security settings</string>
<string name="text_write_secure_settings_description">Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service).</string>
<string name="text_write_system_settings">Write system settings</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1077,5 +1077,14 @@
<string name="text_write_secure_settings">Escribir la configuración de seguridad</string>
<string name="text_write_secure_settings_description">Ajustes de seguridad del sistema, que contienen preferencias del sistema que las aplicaciones pueden leer pero no pueden escribir.\nSe trata de preferencias que el usuario debe modificar explícitamente a través de la interfaz de usuario de una aplicación del sistema.\nCon el permiso de configuración segura del sistema, las aplicaciones normales pueden modificar directamente la configuración segura (como el servicio de accesibilidad).</string>
<string name="text_write_system_settings">Escribir la configuración del sistema</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1077,5 +1077,14 @@
<string name="text_write_secure_settings">Écrire les paramètres de sécurité</string>.
<string name="text_write_secure_settings_description">Paramètres de sécurité du système, contenant les préférences du système que les applications peuvent lire mais ne sont pas autorisées à écrire.\nIl s\'agit des préférences que l\'utilisateur doit explicitement modifier par le biais de l\'interface utilisateur d\'une application système.\nAvec l\'autorisation de paramètres de sécurité du système, les applications normales peuvent directement modifier les paramètres de sécurité (comme le service d\'accessibilité).</string>
<string name="text_write_system_settings">Écrire les paramètres système</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1078,5 +1078,14 @@
<string name="text_write_secure_settings">セキュリティ設定の書き込み</string>
<string name="text_write_secure_settings_description">アプリケーションが読み取ることはできるが, 書き込むことはできないシステム環境設定を含む, 安全なシステム設定です.\nこれは, ユーザーがシステムアプリの UI を通じて明示的に変更する必要がある環境設定のためのものです.\nセキュアなシステム設定を許可すると, 通常のアプリケーションはセキュアな設定 (アクセシビリティサービスなど) を直接変更できるようになります</string>
<string name="text_write_system_settings">システム設定の書き込み</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1079,5 +1079,14 @@
<string name="text_write_secure_settings">보안 설정을 작성하십시오</string>
<string name="text_write_secure_settings_description">애플리케이션이 읽을 수 있지만 쓸 수없는 시스템 환경 설정을 포함하는 보안 시스템 설정.\n이들은 사용자가 시스템 앱의 UI 를 통해 명시 적으로 수정 해야하는 선호도입니다.\n보안 시스템 설정 권한을 사용하면 일반 애플리케이션이 보안 설정 (예: 접근성 서비스)을 직접 수정할 수 있습니다.</string>
<string name="text_write_system_settings">시스템 설정을 작성하십시오</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -6,6 +6,7 @@
<color name="day_night_alpha_70">#B3BFBFBF</color>
<color name="day_night_alpha_60">#9ABFBFBF</color>
<color name="day_night_alpha_50">#80BFBFBF</color>
<color name="day_night_alpha_40">#66BFBFBF</color>
<color name="day_night_alpha_30">#4DBFBFBF</color>
<color name="day_night_alpha_20">#33BFBFBF</color>
<color name="night_day">@color/dawn</color>
@@ -15,7 +16,11 @@
<color name="text_color_primary">@color/day_night</color>
<color name="text_color_primary_full">@color/day_night_full</color>
<color name="text_color_primary_alpha_70">@color/day_night_alpha_70</color>
<color name="text_color_secondly">#808080</color>
<color name="text_color_primary_alpha_50">@color/day_night_alpha_50</color>
<color name="text_color_primary_alpha_40">@color/day_night_alpha_40</color>
<color name="text_color_primary_alpha_30">@color/day_night_alpha_30</color>
<color name="text_color_primary_alpha_20">@color/day_night_alpha_20</color>
<color name="text_color_secondary">#808080</color>
<color name="console_view_debug">#DFE0E0E0</color>
<color name="console_view_verbose">#7F7F80</color>
@@ -49,6 +54,7 @@
<color name="github_avatar_border">#26E2E5EA</color>
<color name="github_color_fg_default">@color/prefTextColorPrimary</color>
<color name="github_color_fg_muted">@color/prefTextColorSecondary</color>
<color name="plugin_center_item_icon_border">#26E2E5EA</color>
<color name="drawer_menu_group_text_color">#808080</color>
<color name="drawer_menu_item_text_color">#9A9A9A</color>

View File

@@ -1077,5 +1077,14 @@
<string name="text_write_secure_settings">Параметры безопасности записи</string>
<string name="text_write_secure_settings_description">Настройки безопасности системы, содержащие системные предпочтения, которые приложения могут читать, но не имеют права записывать.\nОни предназначены для параметров, которые пользователь должен явно изменить через пользовательский интерфейс системного приложения.\nПри наличии разрешения на безопасные системные настройки обычные приложения могут напрямую изменять безопасные настройки (например, служба доступности).</string>
<string name="text_write_system_settings">Запись системных настроек</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1075,5 +1075,14 @@
<string name="text_write_secure_settings">修改安全設置</string>
<string name="text_write_secure_settings_description">安全設置包含應用程序可讀但不可寫入的設置選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設置權限\" 後, 普通應用可直接修改上述安全設置 (例如無障礙服務).</string>
<string name="text_write_system_settings">修改系統設置</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1075,5 +1075,14 @@
<string name="text_write_secure_settings">修改安全設定</string>
<string name="text_write_secure_settings_description">安全設定包含應用程式可讀但不可寫入的設定選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設定許可權\" 後, 普通應用可直接修改上述安全設定 (例如無障礙服務).</string>
<string name="text_write_system_settings">修改系統設定</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -1075,5 +1075,14 @@
<string name="text_write_secure_settings">修改安全设置</string>
<string name="text_write_secure_settings_description">安全设置包含应用程序可读但不可写入的设置选项, 这些选项只能由 UI 或系统级别应用修改.\n被授予 \"修改安全设置权限\" 后, 普通应用可直接修改上述安全设置 (例如无障碍服务).</string>
<string name="text_write_system_settings">修改系统设置</string>
<string name="text_update">更新</string>
<string name="text_plugin_center">插件中心</string>
<string name="text_plugins">插件</string>
<string name="text_updatable">可更新</string>
<string name="text_uninstall">卸载</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 插件中心</string>
<string name="text_app_shortcut_plugin_center_short_label">插件</string>
<string name="text_click_icon_to_add_launcher_shortcut">点击图标添加启动器快捷方式</string>
<string name="text_click_other_areas_to_exit_selection">点击其他区域退出选择</string>
</resources>

View File

@@ -24,6 +24,7 @@
<color name="day_night_alpha_70">#B3212121</color>
<color name="day_night_alpha_60">#9A212121</color>
<color name="day_night_alpha_50">#80212121</color>
<color name="day_night_alpha_40">#66212121</color>
<color name="day_night_alpha_30">#4D212121</color>
<color name="day_night_alpha_20">#33212121</color>
<color name="night_day">@color/night</color>
@@ -35,7 +36,11 @@
<color name="text_color_primary">@color/day_night</color>
<color name="text_color_primary_full">@color/day_night_full</color>
<color name="text_color_primary_alpha_70">@color/day_night_alpha_70</color>
<color name="text_color_secondly">#9DA0A2</color>
<color name="text_color_primary_alpha_50">@color/day_night_alpha_50</color>
<color name="text_color_primary_alpha_40">@color/day_night_alpha_40</color>
<color name="text_color_primary_alpha_30">@color/day_night_alpha_30</color>
<color name="text_color_primary_alpha_20">@color/day_night_alpha_20</color>
<color name="text_color_secondary">#9DA0A2</color>
<color name="black_alpha_40">#66000000</color>
<color name="black_alpha_44">#70000000</color>
@@ -129,6 +134,7 @@
<color name="github_avatar_border">#261B1F24</color>
<color name="github_color_fg_default">#24292F</color>
<color name="github_color_fg_muted">#57606A</color>
<color name="plugin_center_item_icon_border">#261B1F24</color>
<color name="tint_1st_developer_identifier">#2B7A85</color>
<color name="tint_2nd_developer_identifier">#CC7A34</color>

View File

@@ -4,6 +4,8 @@
<dimen name="about_item_avatar_side_length_compat">42dp</dimen>
<dimen name="about_item_avatar_side_length_land">60dp</dimen>
<dimen name="about_item_avatar_side_length_land_compact">54dp</dimen>
<dimen name="plugin_center_item_side_length">64dp</dimen>
<dimen name="plugin_center_item_icon_border_width">1dp</dimen>
<dimen name="content_inset">16dp</dimen>
<dimen name="divider_drawer_menu_group">6dp</dimen>
<dimen name="fab_margin">16dp</dimen>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_app_shortcut_plugin_center_adaptive_background">#68AA1C</color>
</resources>

View File

@@ -54,6 +54,7 @@
<string name="format_dialog_progress_number_format_mega_bytes" translatable="false">%.2fMB/%.2fMB</string>
<string name="id_launcher_shortcut_docs" translatable="false">shortcut_$_docs</string>
<string name="id_launcher_shortcut_log" translatable="false">shortcut_$_log</string>
<string name="id_launcher_shortcut_plugin_center" translatable="false">shortcut_$_plugin_center</string>
<string name="id_launcher_shortcut_settings" translatable="false">shortcut_$_settings</string>
<string name="key_a11y_service" translatable="false">key_$_a11y_service</string>
<string name="key_about_app_and_developer" translatable="false">key_$_about_app_and_developer</string>
@@ -1328,5 +1329,14 @@
<string name="text_write_secure_settings">Write security settings</string>
<string name="text_write_secure_settings_description">Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service).</string>
<string name="text_write_system_settings">Write system settings</string>
<string name="text_update">Update</string>
<string name="text_plugin_center">Plugin center</string>
<string name="text_plugins">Plugins</string>
<string name="text_updatable">Updatable</string>
<string name="text_uninstall">Uninstall</string>
<string name="text_app_shortcut_plugin_center_long_label">AutoJs6 Plugin Center</string>
<string name="text_app_shortcut_plugin_center_short_label">Plugins</string>
<string name="text_click_icon_to_add_launcher_shortcut">Click icon to add launcher shortcut</string>
<string name="text_click_other_areas_to_exit_selection">Click other areas to exit selection</string>
</resources>

View File

@@ -24,7 +24,7 @@
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
<item name="android:itemBackground">@color/item_background</item>
<item name="android:textColorPrimary">@color/text_color_primary</item>
<item name="android:textColorSecondary">@color/text_color_secondly</item>
<item name="android:textColorSecondary">@color/text_color_secondary</item>
<item name="android:windowBackground">@color/window_background</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="colorAccent">@color/colorAccent</item>