Skip to content

Commit 63157af

Browse files
committed
feat(转发聊天记录查看): able to enlarge the image
1 parent 0acf26f commit 63157af

4 files changed

Lines changed: 87 additions & 55 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
package momoi.mod.qqpro
22

3+
import android.view.View
34
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
45
import com.tencent.qqnt.msg.api.impl.MsgServiceImpl
56
import com.tencent.qqnt.msg.api.impl.MsgUtilApiImpl
7+
import momoi.mod.qqpro.hook.view.MyDialogFragment
8+
import java.util.UUID
9+
import kotlin.random.Random
610

711
object MsgUtil {
812
val msgService = MsgServiceImpl()
913
val msgUtilApi = MsgUtilApiImpl()
1014

1115
fun summary(record: MsgRecord) = msgUtilApi.getElementSummary(record)
16+
}
17+
18+
fun View.showDialog(dialog: MyDialogFragment) {
19+
dialog.show(
20+
WatchPicElementExtKt.W(this).childFragmentManager,
21+
Random.nextInt().toString()
22+
)
1223
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package momoi.mod.qqpro.hook.view
2+
3+
import android.annotation.SuppressLint
4+
import android.os.Bundle
5+
import com.tencent.mobileqq.activity.fling.`TopGestureLayout$OnGestureListener`
6+
import com.tencent.qqlive.module.videoreport.inject.fragment.ReportAndroidXDialogFragment
7+
8+
open class MyDialogFragment : ReportAndroidXDialogFragment(),
9+
`TopGestureLayout$OnGestureListener` {
10+
override fun f() {
11+
dismiss()
12+
}
13+
14+
override fun p() {
15+
dismiss()
16+
}
17+
18+
@SuppressLint("ResourceType")
19+
override fun onCreate(savedInstanceState: Bundle?) {
20+
super.onCreate(savedInstanceState)
21+
setStyle(STYLE_NO_TITLE, 2115174655)
22+
}
23+
}

app/src/main/java/momoi/mod/qqpro/hook/view/NetworkImage.kt

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,36 @@ import java.net.URL
1414
import kotlin.concurrent.thread
1515

1616
//TODO 优化逻辑
17-
fun ImageView.loadPicElement(pic: PicElement) {
17+
fun ImageView.loadPicElement(pic: PicElement) = apply {
1818
require(maxHeight != 0)
1919
val cacheFile = context.externalCacheDir!!.child("${pic.md5HexStr}.jpg")
2020
cacheFile.parentFile?.mkdirs()
2121
if (cacheFile.exists()) {
2222
Utils.log("Load Image from disk ${cacheFile.path}")
23-
setImageBitmap(BitmapFactory.decodeFile(cacheFile.absolutePath))
23+
bitmapDecodeFile(cacheFile)
2424
} else {
25-
download(pic.getImageUrl()) { stream ->
26-
if (stream == null) {
25+
download(pic.getImageUrl(), cacheFile) { succeed ->
26+
if (!succeed) {
2727
val error = context.externalCacheDir!!.child("error.jpg")
2828
if (error.exists()) {
2929
bitmapDecodeFile(error)
3030
} else {
31-
download("https://i0.hdslb.com/bfs/new_dyn/e8907352f1c8be0ea696c1447723f6091769278028.png") { errorStream ->
32-
val bitmap = bitmapDecodeStream(errorStream!!)
33-
BufferedOutputStream(error.outputStream()).use {
34-
bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, it)
31+
download("https://i0.hdslb.com/bfs/new_dyn/e8907352f1c8be0ea696c1447723f6091769278028.png", error) {
32+
if (it) {
33+
bitmapDecodeFile(error)
3534
}
3635
}
3736
}
3837
} else {
39-
val bitmap = bitmapDecodeStream(stream)
40-
BufferedOutputStream(cacheFile.outputStream()).use {
41-
bitmap!!.compress(Bitmap.CompressFormat.JPEG, 100, it)
42-
}
38+
bitmapDecodeFile(cacheFile)
4339
}
4440
}
4541
}
4642
}
4743

48-
inline fun download(url: String, crossinline callback: (InputStream?) -> Unit) {
44+
inline fun download(url: String, file: File, crossinline callback: (Boolean) -> Unit) {
4945
thread {
5046
var connection: HttpURLConnection? = null
51-
var inputStream: InputStream? = null
52-
5347
try {
5448
connection = URL(url).openConnection() as HttpURLConnection
5549
connection.connectTimeout = 60_000 // 60秒超时
@@ -59,13 +53,20 @@ inline fun download(url: String, crossinline callback: (InputStream?) -> Unit) {
5953
Utils.log("Download Image From: $url")
6054
connection.connect()
6155
if (connection.responseCode == HttpURLConnection.HTTP_OK) {
62-
callback(connection.inputStream)
56+
if (!file.exists()) {
57+
file.createNewFile()
58+
}
59+
connection.inputStream.use { input ->
60+
file.outputStream().use { out ->
61+
input.copyTo(out)
62+
}
63+
}
6364
} else {
64-
callback(null)
65+
callback(false)
6566
Utils.log("Download Image Failed! $url")
6667
}
6768
} catch (e: Exception) {
68-
callback(null)
69+
callback(false)
6970
e.printStackTrace()
7071
} finally {
7172
connection?.disconnect()
@@ -75,22 +76,19 @@ inline fun download(url: String, crossinline callback: (InputStream?) -> Unit) {
7576

7677
fun ImageView.bitmapDecodeFile(file: File): Bitmap? =
7778
file.inputStream().use {
78-
bitmapDecodeStream(it)
79-
}
80-
fun ImageView.bitmapDecodeStream(inputStream: InputStream): Bitmap? {
81-
val rect = Rect()
82-
BitmapFactory.decodeStream(inputStream, rect, BitmapFactory.Options().apply {
83-
inJustDecodeBounds = true
84-
})
85-
val bitmap = BitmapFactory.decodeStream(inputStream, null, BitmapFactory.Options().apply {
86-
if (rect.height() > maxHeight) {
87-
outHeight = maxHeight
88-
outWidth = (rect.width().toFloat() / rect.height().toFloat() * maxHeight.toFloat()).toInt()
89-
inSampleSize = rect.height() / maxHeight
79+
val rect = Rect()
80+
BitmapFactory.decodeStream(it, rect, BitmapFactory.Options().apply {
81+
inJustDecodeBounds = true
82+
})
83+
val bitmap = BitmapFactory.decodeStream(it, null, BitmapFactory.Options().apply {
84+
if (rect.height() > maxHeight) {
85+
outHeight = maxHeight
86+
outWidth = (rect.width().toFloat() / rect.height().toFloat() * maxHeight.toFloat()).toInt()
87+
inSampleSize = rect.height() / maxHeight
88+
}
89+
})
90+
post {
91+
setImageBitmap(bitmap)
9092
}
91-
})
92-
post {
93-
setImageBitmap(bitmap)
94-
}
95-
return bitmap
96-
}
93+
bitmap
94+
}

app/src/main/java/momoi/mod/qqpro/hook/转发聊天记录查看.kt

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ import com.tencent.qqlive.module.videoreport.inject.fragment.ReportAndroidXDialo
1717
import com.tencent.qqnt.kernel.api.impl.MsgService
1818
import com.tencent.qqnt.kernel.nativeinterface.Contact
1919
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
20+
import com.tencent.qqnt.kernel.nativeinterface.PicElement
2021
import com.tencent.qqnt.msg.KernelServiceUtil
22+
import com.tencent.richframework.widget.matrix.RFWMatrixImageView
2123
import com.tencent.watch.aio_impl.data.WatchAIOMsgItem
2224
import com.tencent.watch.aio_impl.ui.cell.base.BaseWatchItemCell
2325
import com.tencent.watch.aio_impl.ui.cell.unsupport.WatchToQQViewMsgItem
2426
import com.tencent.watch.aio_impl.ui.widget.AIOCellGroupWidget
2527
import loadPicElement
2628
import momoi.anno.mixin.Mixin
2729
import momoi.mod.qqpro.hook.style.MyImageView
30+
import momoi.mod.qqpro.hook.view.MyDialogFragment
2831
import momoi.mod.qqpro.lib.FILL
2932
import momoi.mod.qqpro.hook.view.ReplyView
3033
import momoi.mod.qqpro.lib.background
@@ -48,26 +51,23 @@ import momoi.mod.qqpro.lib.textSize
4851
import momoi.mod.qqpro.lib.vertical
4952
import momoi.mod.qqpro.lib.width
5053
import momoi.mod.qqpro.removeAfter
54+
import momoi.mod.qqpro.showDialog
5155
import momoi.mod.qqpro.util.runOnUi
5256
import momoi.mod.qqpro.warp
5357
import java.util.ArrayList
5458

55-
class DetailFragment(private val contact: Contact, private val data: MultiMsgData) : ReportAndroidXDialogFragment(),
56-
`TopGestureLayout$OnGestureListener` {
57-
override fun f() {
58-
dismiss()
59-
}
60-
61-
override fun p() {
62-
dismiss()
63-
}
64-
65-
@SuppressLint("ResourceType")
66-
override fun onCreate(savedInstanceState: Bundle?) {
67-
super.onCreate(savedInstanceState)
68-
setStyle(STYLE_NO_TITLE, 2115174655)
59+
class BigImageFragment(private val pic: PicElement) : MyDialogFragment() {
60+
override fun onCreateView(
61+
inflater: LayoutInflater,
62+
container: ViewGroup?,
63+
savedInstanceState: Bundle?
64+
): View {
65+
return RFWMatrixImageView(inflater.context, null)
66+
.size(FILL, FILL)
67+
.loadPicElement(pic)
6968
}
70-
69+
}
70+
class DetailFragment(private val contact: Contact, private val data: MultiMsgData) : MyDialogFragment() {
7171
private val mMsgList = mutableListOf<MsgRecord>()
7272
private lateinit var mRv: RecyclerView
7373
@SuppressLint("NotifyDataSetChanged")
@@ -145,6 +145,9 @@ class DetailFragment(private val contact: Contact, private val data: MultiMsgDat
145145
ele.picElement?.let {
146146
add<MyImageView>()
147147
.size(it.picWidth, it.picHeight)
148+
.clickable {
149+
showDialog(BigImageFragment(it))
150+
}
148151
.loadPicElement(it)
149152
return@forEach
150153
}
@@ -174,10 +177,7 @@ class MultiMsgCellGroup(context: Context) : AIOCellGroupWidget(context) {
174177
.vertical()
175178
.padding(2.dp)
176179
.clickable {
177-
DetailFragment(contact, data).show(
178-
WatchPicElementExtKt.W(this).childFragmentManager,
179-
"MultiMsgDetail"
180-
)
180+
showDialog(DetailFragment(contact, data))
181181
}
182182
.content {
183183
add<TextView>()

0 commit comments

Comments
 (0)