Skip to content

Commit 42e0e2c

Browse files
authored
Merge pull request #1082 from wangwang-code/patch-8-31-4
V3 作者自我介绍支持翻译与长简介折叠
2 parents 9d482ac + 27162c6 commit 42e0e2c

2 files changed

Lines changed: 140 additions & 18 deletions

File tree

app/src/main/java/ceui/lisa/activities/UserV3InfoFragment.kt

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import android.view.LayoutInflater
66
import android.view.View
77
import android.view.ViewGroup
88
import android.widget.LinearLayout
9+
import androidx.core.view.OneShotPreDrawListener
10+
import androidx.core.view.doOnPreDraw
911
import androidx.core.view.isVisible
1012
import androidx.core.view.doOnPreDraw
1113
import androidx.databinding.DataBindingUtil
@@ -20,8 +22,12 @@ import ceui.lisa.utils.PixivOperate
2022
import ceui.lisa.viewmodel.UserViewModel
2123
import ceui.loxia.Event
2224
import ceui.loxia.WebUserDetail
25+
import ceui.pixiv.ui.comments.translateComment
2326
import ceui.pixiv.session.SessionManager
2427

28+
/** 作者简介折叠阈值,与 V3 详情页简介一致。 */
29+
private const val BIO_COLLAPSED_LINES = 5
30+
2531
/**
2632
* V3 用户主页右侧 Tab —— 资料 / 工作环境 / 社交链接 / 简介 / 屏蔽。
2733
*
@@ -33,6 +39,10 @@ class UserV3InfoFragment : Fragment() {
3339
private val binding get() = _binding!!
3440
private val userViewModel: UserViewModel by activityViewModels()
3541

42+
/** 作者简介展开态(对齐 V3 详情页简介折叠)。 */
43+
private var bioExpanded = false
44+
private var bioFullText: CharSequence? = null
45+
3646
override fun onCreateView(
3747
inflater: LayoutInflater,
3848
container: ViewGroup?,
@@ -74,25 +84,85 @@ class UserV3InfoFragment : Fragment() {
7484
binding.muteSwitch.setOnCheckedChangeListener(muteSwitchListener)
7585
}
7686
}
87+
binding.bioTranslate.setOnClickListener { translateBio() }
88+
binding.bioToggle.setOnClickListener {
89+
bioExpanded = !bioExpanded
90+
applyBioCollapseState()
91+
}
7792
}
7893

7994
override fun onDestroyView() {
95+
clearPendingBioPreDraw()
96+
bioFullText = null
8097
super.onDestroyView()
8198
_binding = null
8299
}
83100

101+
private fun bindBio(full: CharSequence) {
102+
bioFullText = full
103+
binding.bioSection.isVisible = true
104+
binding.bio.text = full
105+
binding.bio.movementMethod = android.text.method.LinkMovementMethod.getInstance()
106+
applyBioCollapseState()
107+
}
108+
109+
private fun translateBio() {
110+
val plain = (bioFullText ?: binding.bio.text).toString().trim()
111+
translateComment(plain)
112+
}
113+
114+
/**
115+
* 长简介折叠,对齐 V3 详情页简介区:#965/#1005 同款实现口径。
116+
* 折叠态在文本层面截到第 [BIO_COLLAPSED_LINES] 行止,避免 textIsSelectable /
117+
* LinkMovementMethod 把隐藏行滚出来。
118+
*/
119+
private fun applyBioCollapseState() {
120+
val full = bioFullText ?: return
121+
binding.bio.maxLines = if (bioExpanded) Int.MAX_VALUE else BIO_COLLAPSED_LINES
122+
binding.bio.text = full
123+
binding.bio.scrollTo(0, 0)
124+
binding.bioToggle.setText(
125+
if (bioExpanded) R.string.v3_desc_collapse else R.string.v3_desc_expand
126+
)
127+
clearPendingBioPreDraw()
128+
lateinit var request: OneShotPreDrawListener
129+
request = binding.bio.doOnPreDraw {
130+
if (binding.bio.getTag(R.id.v3_desc_predraw_listener) === request &&
131+
bioFullText === full
132+
) {
133+
binding.bio.setTag(R.id.v3_desc_predraw_listener, null)
134+
val layout = binding.bio.layout
135+
if (layout != null) {
136+
val overflow = layout.lineCount > BIO_COLLAPSED_LINES
137+
binding.bioToggle.isVisible = overflow
138+
if (!bioExpanded && overflow) {
139+
val end = layout.getLineEnd(BIO_COLLAPSED_LINES - 1).coerceIn(0, full.length)
140+
binding.bio.text = full.subSequence(0, end).trimEnd()
141+
}
142+
}
143+
}
144+
}
145+
binding.bio.setTag(R.id.v3_desc_predraw_listener, request)
146+
}
147+
148+
private fun clearPendingBioPreDraw() {
149+
(binding.bio.getTag(R.id.v3_desc_predraw_listener) as? OneShotPreDrawListener)
150+
?.removeListener()
151+
binding.bio.setTag(R.id.v3_desc_predraw_listener, null)
152+
}
153+
84154
private fun bindUserDetail(data: UserDetailResponse) {
85155
val user = data.user
86156
val profile = data.profile
87157
val isSelf = user.id == SessionManager.loggedInUid
88158

89159
// Bio
90160
if (!TextUtils.isEmpty(user.comment)) {
91-
binding.bio.visibility = View.VISIBLE
92-
binding.bio.text = androidx.core.text.HtmlCompat.fromHtml(
93-
user.comment.orEmpty(), androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
161+
bindBio(
162+
androidx.core.text.HtmlCompat.fromHtml(
163+
user.comment.orEmpty(), androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
164+
)
94165
)
95-
binding.bio.movementMethod = android.text.method.LinkMovementMethod.getInstance()
96166
}
97167

98168
// Social chips from app API (web API may add more later)
@@ -114,11 +184,11 @@ class UserV3InfoFragment : Fragment() {
114184
private fun bindWebUserDetail(detail: WebUserDetail) {
115185
// Web 端的 commentHtml 比 app 端的 user.comment 排版更全(有 <a> 等标签),有就覆盖。
116186
if (!detail.commentHtml.isNullOrEmpty()) {
117-
binding.bio.isVisible = true
118-
binding.bio.text = androidx.core.text.HtmlCompat.fromHtml(
119-
detail.commentHtml, androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
187+
bindBio(
188+
androidx.core.text.HtmlCompat.fromHtml(
189+
detail.commentHtml, androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
190+
)
120191
)
121-
binding.bio.movementMethod = android.text.method.LinkMovementMethod.getInstance()
122192
}
123193

124194
// Supplement social links from Web API

app/src/main/res/layout/fragment_user_v3_info.xml

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,71 @@
8080
</LinearLayout>
8181

8282
<!-- Bio (between profile and workspace) -->
83-
<TextView
84-
android:id="@+id/bio"
83+
<LinearLayout
84+
android:id="@+id/bio_section"
8585
android:layout_width="match_parent"
8686
android:layout_height="wrap_content"
8787
android:layout_marginTop="16dp"
88-
android:alpha="0.78"
89-
android:autoLink="all"
90-
android:lineSpacingMultiplier="1.6"
91-
android:textColor="@color/v3_text_1"
92-
android:textColorLink="#3D8BFD"
93-
android:textIsSelectable="true"
94-
android:textSize="14sp"
95-
android:visibility="gone" />
88+
android:orientation="vertical"
89+
android:visibility="gone">
90+
91+
<LinearLayout
92+
android:layout_width="match_parent"
93+
android:layout_height="wrap_content"
94+
android:gravity="center_vertical"
95+
android:orientation="horizontal">
96+
97+
<TextView
98+
android:layout_width="wrap_content"
99+
android:layout_height="wrap_content"
100+
android:letterSpacing="0.12"
101+
android:text="@string/label_personal_intro"
102+
android:textAllCaps="true"
103+
android:textColor="@color/v3_text_3"
104+
android:textSize="12sp"
105+
android:textStyle="bold" />
106+
107+
<View
108+
android:layout_width="0dp"
109+
android:layout_height="0dp"
110+
android:layout_weight="1" />
111+
112+
<ImageView
113+
android:id="@+id/bio_translate"
114+
android:layout_width="48dp"
115+
android:layout_height="48dp"
116+
android:background="?attr/selectableItemBackgroundBorderless"
117+
android:padding="12dp"
118+
android:contentDescription="@string/string_translate_caption"
119+
android:src="@drawable/ic_baseline_translate_24"
120+
app:tint="@color/v3_text_3" />
121+
</LinearLayout>
122+
123+
<TextView
124+
android:id="@+id/bio"
125+
android:layout_width="match_parent"
126+
android:layout_height="wrap_content"
127+
android:alpha="0.78"
128+
android:autoLink="all"
129+
android:lineSpacingMultiplier="1.6"
130+
android:textColor="@color/v3_text_1"
131+
android:textColorLink="#3D8BFD"
132+
android:textIsSelectable="true"
133+
android:textSize="14sp" />
134+
135+
<TextView
136+
android:id="@+id/bio_toggle"
137+
android:layout_width="match_parent"
138+
android:layout_height="wrap_content"
139+
android:background="?attr/selectableItemBackground"
140+
android:gravity="center_vertical"
141+
android:minHeight="48dp"
142+
android:text="@string/v3_desc_expand"
143+
android:textColor="@color/v3_blue"
144+
android:textSize="13sp"
145+
android:textStyle="bold"
146+
android:visibility="gone" />
147+
</LinearLayout>
96148

97149
<!-- Workspace Card -->
98150
<LinearLayout

0 commit comments

Comments
 (0)