feat: 插件管理界面
This commit is contained in:
parent
c2af149d1d
commit
bfcdf1b553
|
|
@ -39,17 +39,27 @@
|
|||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<activity android:name=".activities.HotMessageListActivity" />
|
||||
<activity
|
||||
android:name=".activities.PluginManageActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:label="@string/title_plugin_manage" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.HotMessageListActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.PhotoViewActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:theme="@style/AppTheme.PhotoView"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/AppTheme.PhotoView" />
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.BootCompleteSignReceiver"
|
||||
|
|
@ -122,8 +132,8 @@
|
|||
|
||||
<activity
|
||||
android:name=".activities.HistoryActivity"
|
||||
android:label="@string/title_history"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:label="@string/title_history"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity android:name=".activities.OKSignActivity">
|
||||
<intent-filter>
|
||||
|
|
@ -199,8 +209,8 @@
|
|||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activities.UserCollectActivity"
|
||||
android:label="@string/title_my_collect"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:label="@string/title_my_collect"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activities.MessageActivity"
|
||||
|
|
@ -236,8 +246,8 @@
|
|||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activities.ForumInfoActivity"
|
||||
android:label="@string/title_forum_info"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:label="@string/title_forum_info"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
|
|
@ -250,8 +260,8 @@
|
|||
<activity
|
||||
android:name=".activities.AppThemeActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:label="@string/title_theme_settings" />
|
||||
android:label="@string/title_theme_settings"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<receiver android:name=".receivers.AutoSignAlarm" />
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
"id": "CommentLookup",
|
||||
"name": "发言查询",
|
||||
"desc": "使用第三方工具箱查询用户过往发言",
|
||||
"author": "huanchengfly",
|
||||
"version": "1.0",
|
||||
"main_class": "com.huanchengfly.tieba.post.plugins.PluginCommentLookup"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ class BaseApplication : Application(), IApp {
|
|||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
override fun onActivityDestroyed(activity: Activity) {}
|
||||
})
|
||||
CrashUtil.CrashHandler.getInstance().init(this)
|
||||
if (BuildConfig.DEBUG) CrashUtil.CrashHandler.getInstance().init(this)
|
||||
PluginManager.init(this)
|
||||
}
|
||||
|
||||
|
|
@ -472,6 +472,6 @@ class BaseApplication : Application(), IApp {
|
|||
}
|
||||
|
||||
override fun launchUrl(url: String) {
|
||||
launchUrl(this, url)
|
||||
launchUrl(mActivityList.lastOrNull() ?: this, url)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.huanchengfly.tieba.post.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import butterknife.BindView
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.adapters.PluginManageAdapter
|
||||
import com.huanchengfly.tieba.post.components.dividers.SpacesItemDecoration
|
||||
import com.huanchengfly.tieba.post.dpToPx
|
||||
import com.huanchengfly.tieba.post.plugins.PluginManager
|
||||
import com.huanchengfly.tieba.post.utils.ThemeUtil
|
||||
|
||||
class PluginManageActivity : BaseActivity() {
|
||||
@BindView(R.id.toolbar)
|
||||
lateinit var toolbar: Toolbar
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
lateinit var collapsingToolbar: CollapsingToolbarLayout
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
lateinit var recyclerView: RecyclerView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background))
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.title = title
|
||||
collapsingToolbar.title = title
|
||||
PluginManager.reloadPluginManifests()
|
||||
recyclerView.apply {
|
||||
adapter = PluginManageAdapter(this@PluginManageActivity)
|
||||
layoutManager = LinearLayoutManager(this@PluginManageActivity)
|
||||
addItemDecoration(SpacesItemDecoration(0, 0, 0, 8.dpToPx()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_plugin_manage
|
||||
}
|
||||
}
|
||||
|
|
@ -219,7 +219,6 @@ class UserActivity : BaseActivity() {
|
|||
}
|
||||
}
|
||||
return if (PluginManager.performPluginMenuClick(
|
||||
this,
|
||||
PluginManager.MENU_USER_ACTIVITY,
|
||||
item.itemId,
|
||||
profileBean
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.huanchengfly.tieba.post.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.edit
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.adapters.base.BaseSingleTypeAdapter
|
||||
import com.huanchengfly.tieba.post.components.MyViewHolder
|
||||
import com.huanchengfly.tieba.post.plugins.PluginManager
|
||||
import com.huanchengfly.tieba.post.plugins.models.PluginManifest
|
||||
import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil
|
||||
|
||||
class PluginManageAdapter(context: Context) :
|
||||
BaseSingleTypeAdapter<PluginManifest>(context, PluginManager.pluginManifests) {
|
||||
val preferences: SharedPreferences
|
||||
get() = SharedPreferencesUtil.get(SharedPreferencesUtil.SP_PLUGINS)
|
||||
|
||||
override fun getItemLayoutId(): Int {
|
||||
return R.layout.item_plugin_list
|
||||
}
|
||||
|
||||
override fun convert(viewHolder: MyViewHolder, item: PluginManifest, position: Int) {
|
||||
viewHolder.setText(R.id.plugin_name, item.name)
|
||||
viewHolder.setText(
|
||||
R.id.plugin_info,
|
||||
context.getString(R.string.template_plugin_info, item.version, item.author)
|
||||
)
|
||||
viewHolder.setText(R.id.plugin_desc, item.desc)
|
||||
viewHolder.getView<SwitchCompat>(R.id.plugin_status).apply {
|
||||
isChecked = preferences.getBoolean("${item.id}_enabled", false)
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
preferences.edit(commit = true) {
|
||||
putBoolean("${item.id}_enabled", isChecked)
|
||||
}
|
||||
PluginManager.reloadPlugins()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
PluginManager.reloadPluginManifests()
|
||||
setData(PluginManager.pluginManifests)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,11 +33,11 @@ inline fun <reified Data> IPlugin.registerMenuItem(
|
|||
inline fun <reified Data> IPlugin.registerMenuItem(
|
||||
id: String,
|
||||
title: String,
|
||||
crossinline callback: (Context, Data) -> Unit
|
||||
crossinline callback: (Data) -> Unit
|
||||
) {
|
||||
registerMenuItem(id, title, object : ClickCallback<Data> {
|
||||
override fun onClick(context: Context, data: Data) {
|
||||
callback.invoke(context, data)
|
||||
override fun onClick(data: Data) {
|
||||
callback.invoke(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.huanchengfly.tieba.post.R
|
|||
import com.huanchengfly.tieba.post.api.models.ProfileBean
|
||||
import com.huanchengfly.tieba.post.plugins.interfaces.IApp
|
||||
import com.huanchengfly.tieba.post.plugins.models.PluginManifest
|
||||
import com.huanchengfly.tieba.post.utils.launchUrl
|
||||
|
||||
class PluginCommentLookup(app: IApp, manifest: PluginManifest) : IPlugin(app, manifest) {
|
||||
override fun onEnable() {
|
||||
|
|
@ -12,8 +11,8 @@ class PluginCommentLookup(app: IApp, manifest: PluginManifest) : IPlugin(app, ma
|
|||
registerMenuItem<ProfileBean>(
|
||||
"lookup_comment",
|
||||
context.getString(R.string.plugin_comment_lookup_menu)
|
||||
) { context, data ->
|
||||
launchUrl(context, "https://www.82cat.com/tieba/reply/${data.user?.name}/1")
|
||||
) { data ->
|
||||
app.launchUrl("https://www.82cat.com/tieba/reply/${data.user?.name}/1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,11 @@ object PluginManager {
|
|||
get() = SharedPreferencesUtil.get(SP_PLUGINS)
|
||||
|
||||
init {
|
||||
reloadPluginMenu()
|
||||
}
|
||||
|
||||
private fun reloadPluginMenu() {
|
||||
registeredPluginMenuItems.clear()
|
||||
listOf(
|
||||
MENU_USER_ACTIVITY,
|
||||
MENU_NONE
|
||||
|
|
@ -56,7 +61,6 @@ object PluginManager {
|
|||
}
|
||||
|
||||
fun <Data> performPluginMenuClick(
|
||||
context: Context,
|
||||
menuId: String,
|
||||
itemId: Int,
|
||||
data: Data
|
||||
|
|
@ -67,7 +71,7 @@ object PluginManager {
|
|||
return false
|
||||
}
|
||||
return try {
|
||||
(item as PluginMenuItem<Data>).callback!!.onClick(context, data)
|
||||
(item as PluginMenuItem<Data>).callback!!.onClick(data)
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
|
|
@ -132,10 +136,11 @@ object PluginManager {
|
|||
destroyPlugin(it)
|
||||
}
|
||||
pluginInstances.clear()
|
||||
reloadPluginMenu()
|
||||
reloadPluginManifests()
|
||||
pluginManifests.forEach {
|
||||
try {
|
||||
if (!it.pluginCreated && preferences.getBoolean("${it.id}_enabled", true)) {
|
||||
if (!it.pluginCreated && preferences.getBoolean("${it.id}_enabled", false)) {
|
||||
val pluginInstance = createPlugin(it)
|
||||
if (pluginInstance != null) {
|
||||
pluginInstances.add(pluginInstance)
|
||||
|
|
@ -163,7 +168,7 @@ class PluginMenuItem<Data>(
|
|||
val callback: ClickCallback<Data>? = null
|
||||
) {
|
||||
interface ClickCallback<Data> {
|
||||
fun onClick(context: Context, data: Data)
|
||||
fun onClick(data: Data)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ data class PluginManifest(
|
|||
val name: String,
|
||||
val desc: String,
|
||||
val version: String,
|
||||
val author: String,
|
||||
@SerializedName("main_class")
|
||||
val mainClass: String
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20.5,11H19V7c0,-1.1 -0.9,-2 -2,-2h-4V3.5C13,2.12 11.88,1 10.5,1S8,2.12 8,3.5V5H4c-1.1,0 -1.99,0.9 -1.99,2v3.8H3.5c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7H2V20c0,1.1 0.9,2 2,2h3.8v-1.5c0,-1.49 1.21,-2.7 2.7,-2.7s2.7,1.21 2.7,2.7V22H17c1.1,0 2,-0.9 2,-2v-4h1.5c1.38,0 2.5,-1.12 2.5,-2.5S21.88,11 20.5,11z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintCoordinatorLayout 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"
|
||||
app:backgroundTint="@color/default_color_window_background"
|
||||
tools:context=".activities.PluginManageActivity">
|
||||
|
||||
<include layout="@layout/layout_new_appbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:paddingStart="@dimen/card_margin"
|
||||
android:paddingEnd="@dimen/card_margin"
|
||||
android:paddingTop="@dimen/card_margin"
|
||||
android:clipToPadding="false"
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
</com.huanchengfly.tieba.post.widgets.theme.TintCoordinatorLayout>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintLinearLayout 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:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="@drawable/bg_radius_10dp"
|
||||
app:backgroundTint="@color/default_color_card">
|
||||
|
||||
<LinearLayout
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/plugin_name"
|
||||
app:tint="@color/default_color_text"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:singleLine="true"
|
||||
tools:text="插件名称" />
|
||||
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/plugin_info"
|
||||
app:tint="@color/default_color_text_secondary"
|
||||
android:textSize="14sp"
|
||||
android:singleLine="true"
|
||||
tools:text="v1.0 · 作者 huanchengfly" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintSwitch
|
||||
style="@style/Widget.Switch"
|
||||
android:minHeight="0dp"
|
||||
android:id="@+id/plugin_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.huanchengfly.tieba.post.widgets.theme.TintTextView
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/plugin_desc"
|
||||
app:tint="@color/default_color_text_secondary"
|
||||
android:textSize="14sp"
|
||||
tools:text="这是一个示例插件" />
|
||||
|
||||
</com.huanchengfly.tieba.post.widgets.theme.TintLinearLayout>
|
||||
|
|
@ -466,4 +466,6 @@
|
|||
<string name="title_theme_translucent">透明主题</string>
|
||||
<string name="title_theme_custom">自定义</string>
|
||||
<string name="plugin_comment_lookup_menu">查询发言</string>
|
||||
<string name="title_plugin_manage">附加功能管理</string>
|
||||
<string name="template_plugin_info">v%1$s · 作者 %2$s</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -120,6 +120,16 @@
|
|||
android:key="forumFabFunction"
|
||||
android:title="@string/settings_forum_fab_function" />
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_round_extension"
|
||||
android:key="plugin_manage"
|
||||
android:title="@string/title_plugin_manage">
|
||||
<intent
|
||||
android:targetPackage="com.huanchengfly.tieba.post"
|
||||
android:targetClass="com.huanchengfly.tieba.post.activities.PluginManageActivity"
|
||||
android:action="android.intent.action.VIEW" />
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:enabled="false"
|
||||
android:layout="@layout/layout_preference_bottom" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue