feat: 插件菜单入口

This commit is contained in:
HuanChengFly 2021-08-15 18:30:51 +08:00
parent c306846e7e
commit c2af149d1d
7 changed files with 80 additions and 30 deletions

View File

@ -1,9 +1,11 @@
[
{
"plugins": [
{
"id": "CommentLookup",
"name": "发言查询",
"desc": "使用第三方工具箱查询用户过往发言",
"version": "1.0",
"mainClass": "com.huanchengfly.tieba.post.plugins.PluginCommentLookup"
"main_class": "com.huanchengfly.tieba.post.plugins.PluginCommentLookup"
}
]
]
}

View File

@ -11,7 +11,6 @@ import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
@ -41,26 +40,25 @@ class BaseApplication : Application(), IApp {
instance = this
super.onCreate()
ThemeUtils.init(ThemeDelegate)
PluginManager.init(this)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
LitePal.initialize(this)
FlurryAgent.Builder()
.withCaptureUncaughtExceptions(true)
.build(this, "ZMRX6W76WNF95ZHT857X")
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
private var clipBoardHash: String? = null
private var clipBoardHash: Int = 0
private fun updateClipBoardHashCode() {
clipBoardHash = getClipBoardHash()
}
private fun getClipBoardHash(): String? {
private fun getClipBoardHash(): Int {
val cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val data = cm.primaryClip
if (data != null) {
val item = data.getItemAt(0)
return item.toString().toMD5()
return item.hashCode()
}
return null
return 0
}
private val clipBoard: String
@ -117,8 +115,9 @@ class BaseApplication : Application(), IApp {
}
override fun onActivityResumed(activity: Activity) {
if (!TextUtils.equals(clipBoardHash, getClipBoardHash())) {
@RegExp val regex = "((http|https)://)(([a-zA-Z0-9._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9&%_./-~-]*)?"
if (clipBoardHash != getClipBoardHash()) {
@RegExp val regex =
"((http|https)://)(([a-zA-Z0-9._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9&%_./-~-]*)?"
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(clipBoard)
if (matcher.find()) {
@ -127,7 +126,8 @@ class BaseApplication : Application(), IApp {
if (isTiebaDomain(uri.host)) {
val previewView = Util.inflate(activity, R.layout.preview_url)
if (isForumUrl(uri)) {
updatePreviewView(activity, previewView, PreviewInfo()
updatePreviewView(
activity, previewView, PreviewInfo()
.setIconRes(R.drawable.ic_round_forum)
.setTitle(activity.getString(R.string.title_forum, getForumName(uri)))
.setSubtitle(activity.getString(R.string.text_loading))
@ -174,6 +174,7 @@ class BaseApplication : Application(), IApp {
override fun onActivityDestroyed(activity: Activity) {}
})
CrashUtil.CrashHandler.getInstance().init(this)
PluginManager.init(this)
}
/**

View File

@ -30,6 +30,7 @@ import com.huanchengfly.tieba.post.fragments.UserPostFragment
import com.huanchengfly.tieba.post.goToActivity
import com.huanchengfly.tieba.post.models.PhotoViewBean
import com.huanchengfly.tieba.post.models.database.Block
import com.huanchengfly.tieba.post.plugins.PluginManager
import com.huanchengfly.tieba.post.utils.AccountUtil
import com.huanchengfly.tieba.post.utils.ImageUtil
import com.huanchengfly.tieba.post.utils.StatusBarUtil
@ -187,6 +188,7 @@ class UserActivity : BaseActivity() {
menu.findItem(R.id.menu_block).isVisible = true
menu.findItem(R.id.menu_edit_info).isVisible = false
}
PluginManager.initPluginMenu(menu, PluginManager.MENU_USER_ACTIVITY)
return super.onCreateOptionsMenu(menu)
}
@ -205,7 +207,8 @@ class UserActivity : BaseActivity() {
.saveAsync()
.listen { success: Boolean ->
if (success) {
Toast.makeText(this, R.string.toast_add_success, Toast.LENGTH_SHORT).show()
Toast.makeText(this, R.string.toast_add_success, Toast.LENGTH_SHORT)
.show()
}
}
return true
@ -215,7 +218,17 @@ class UserActivity : BaseActivity() {
return true
}
}
return super.onOptionsItemSelected(item)
return if (PluginManager.performPluginMenuClick(
this,
PluginManager.MENU_USER_ACTIVITY,
item.itemId,
profileBean
)
) {
true
} else {
super.onOptionsItemSelected(item)
}
}
@OnClick(R.id.user_center_action_btn)

View File

@ -33,11 +33,11 @@ inline fun <reified Data> IPlugin.registerMenuItem(
inline fun <reified Data> IPlugin.registerMenuItem(
id: String,
title: String,
crossinline callback: (Data) -> Unit
crossinline callback: (Context, Data) -> Unit
) {
registerMenuItem(id, title, object : ClickCallback<Data> {
override fun onClick(data: Data) {
callback.invoke(data)
override fun onClick(context: Context, data: Data) {
callback.invoke(context, data)
}
})
}

View File

@ -4,6 +4,7 @@ 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() {
@ -11,8 +12,8 @@ class PluginCommentLookup(app: IApp, manifest: PluginManifest) : IPlugin(app, ma
registerMenuItem<ProfileBean>(
"lookup_comment",
context.getString(R.string.plugin_comment_lookup_menu)
) {
app.launchUrl("https://www.82cat.com/tieba/reply/${it.user?.name}/1")
) { context, data ->
launchUrl(context, "https://www.82cat.com/tieba/reply/${data.user?.name}/1")
}
}
}

View File

@ -2,9 +2,11 @@ package com.huanchengfly.tieba.post.plugins
import android.content.Context
import android.content.SharedPreferences
import android.view.Menu
import com.huanchengfly.tieba.post.api.models.ProfileBean
import com.huanchengfly.tieba.post.fromJson
import com.huanchengfly.tieba.post.plugins.interfaces.IApp
import com.huanchengfly.tieba.post.plugins.models.BuiltInPlugins
import com.huanchengfly.tieba.post.plugins.models.PluginManifest
import com.huanchengfly.tieba.post.utils.AssetUtil
import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil
@ -19,7 +21,7 @@ object PluginManager {
val pluginManifests: MutableList<PluginManifest> = mutableListOf()
val pluginInstances: MutableList<IPlugin> = mutableListOf()
val registeredPluginMenuItems: MutableMap<String, MutableMap<String, PluginMenuItem<*>>> =
val registeredPluginMenuItems: MutableMap<String, MutableMap<Int, PluginMenuItem<*>>> =
mutableMapOf()
val context: Context
@ -37,7 +39,7 @@ object PluginManager {
}
fun <Data> registerMenuItem(pluginInstance: IPlugin, menuItem: PluginMenuItem<Data>) {
registeredPluginMenuItems[menuItem.menuId]!!["${pluginInstance.manifest.id}_${menuItem.id}"] =
registeredPluginMenuItems[menuItem.menuId]!!["${pluginInstance.manifest.id}_${menuItem.id}".hashCode()] =
menuItem
}
@ -46,6 +48,32 @@ object PluginManager {
reloadPlugins()
}
fun initPluginMenu(menu: Menu, menuId: String) {
val menuItems = registeredPluginMenuItems[menuId]!!
menuItems.forEach {
menu.add(0, it.key, 0, it.value.title)
}
}
fun <Data> performPluginMenuClick(
context: Context,
menuId: String,
itemId: Int,
data: Data
): Boolean {
val menuItems = registeredPluginMenuItems[menuId]!!
val item = menuItems[itemId]
if (item?.callback == null) {
return false
}
return try {
(item as PluginMenuItem<Data>).callback!!.onClick(context, data)
true
} catch (e: Exception) {
false
}
}
fun enablePlugin(id: String) {
pluginInstances.filter { it.manifest.id == id }.forEach { enablePlugin(it) }
}
@ -94,7 +122,7 @@ object PluginManager {
fun reloadPluginManifests() {
pluginManifests.clear()
pluginManifests.addAll(
AssetUtil.getStringFromAsset(context, "plugins.json").fromJson<List<PluginManifest>>()
AssetUtil.getStringFromAsset(context, "plugins.json").fromJson<BuiltInPlugins>().plugins
)
}
@ -107,7 +135,7 @@ object PluginManager {
reloadPluginManifests()
pluginManifests.forEach {
try {
if (it.pluginCreated && preferences.getBoolean("${it.id}_enabled", true)) {
if (!it.pluginCreated && preferences.getBoolean("${it.id}_enabled", true)) {
val pluginInstance = createPlugin(it)
if (pluginInstance != null) {
pluginInstances.add(pluginInstance)
@ -135,7 +163,7 @@ class PluginMenuItem<Data>(
val callback: ClickCallback<Data>? = null
) {
interface ClickCallback<Data> {
fun onClick(data: Data)
fun onClick(context: Context, data: Data)
}
override fun equals(other: Any?): Boolean {

View File

@ -0,0 +1,5 @@
package com.huanchengfly.tieba.post.plugins.models
data class BuiltInPlugins(
val plugins: List<PluginManifest>
)