update minSdk to 24, cleanup code (#4014)
closes https://github.com/tuskyapp/Tusky/issues/2607 redo of https://github.com/tuskyapp/Tusky/pull/3593
This commit is contained in:
parent
0768dcd374
commit
7dfc8790c7
16 changed files with 72 additions and 204 deletions
|
|
@ -679,17 +679,12 @@ public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
);
|
||||
LinkHelper.setClickableText(statusContent, emojifiedText, statusViewData.getActionable().getMentions(), statusViewData.getActionable().getTags(), listener);
|
||||
|
||||
CharSequence emojifiedContentWarning;
|
||||
if (statusViewData.getSpoilerText() != null) {
|
||||
emojifiedContentWarning = CustomEmojiHelper.emojify(
|
||||
statusViewData.getSpoilerText(),
|
||||
CharSequence emojifiedContentWarning = CustomEmojiHelper.emojify(
|
||||
statusViewData.getStatus().getSpoilerText(),
|
||||
statusViewData.getActionable().getEmojis(),
|
||||
contentWarningDescriptionTextView,
|
||||
statusDisplayOptions.animateEmojis()
|
||||
);
|
||||
} else {
|
||||
emojifiedContentWarning = "";
|
||||
}
|
||||
contentWarningDescriptionTextView.setText(emojifiedContentWarning);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
final StatusActionListener listener) {
|
||||
|
||||
Status actionable = status.getActionable();
|
||||
String spoilerText = status.getSpoilerText();
|
||||
String spoilerText = actionable.getSpoilerText();
|
||||
List<Emoji> emojis = actionable.getEmojis();
|
||||
|
||||
boolean sensitive = !TextUtils.isEmpty(spoilerText);
|
||||
|
|
@ -764,7 +764,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
if (payloads == null) {
|
||||
Status actionable = status.getActionable();
|
||||
setDisplayName(actionable.getAccount().getName(), actionable.getAccount().getEmojis(), statusDisplayOptions);
|
||||
setUsername(status.getUsername());
|
||||
setUsername(actionable.getAccount().getUsername());
|
||||
setMetaData(status, statusDisplayOptions, listener);
|
||||
setIsReply(actionable.getInReplyToId() != null);
|
||||
setReplyCount(actionable.getRepliesCount(), statusDisplayOptions.showStatsInline());
|
||||
|
|
@ -860,11 +860,11 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
String description = context.getString(R.string.description_status,
|
||||
actionable.getAccount().getDisplayName(),
|
||||
getContentWarningDescription(context, status),
|
||||
(TextUtils.isEmpty(status.getSpoilerText()) || !actionable.getSensitive() || status.isExpanded() ? status.getContent() : ""),
|
||||
(TextUtils.isEmpty(actionable.getSpoilerText()) || !actionable.getSensitive() || status.isExpanded() ? status.getContent() : ""),
|
||||
getCreatedAtDescription(actionable.getCreatedAt(), statusDisplayOptions),
|
||||
actionable.getEditedAt() != null ? context.getString(R.string.description_post_edited) : "",
|
||||
getReblogDescription(context, status),
|
||||
status.getUsername(),
|
||||
actionable.getAccount().getUsername(),
|
||||
actionable.getReblogged() ? context.getString(R.string.description_post_reblogged) : "",
|
||||
actionable.getFavourited() ? context.getString(R.string.description_post_favourited) : "",
|
||||
actionable.getBookmarked() ? context.getString(R.string.description_post_bookmarked) : "",
|
||||
|
|
@ -911,8 +911,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
|
||||
private static CharSequence getContentWarningDescription(Context context,
|
||||
@NonNull StatusViewData.Concrete status) {
|
||||
if (!TextUtils.isEmpty(status.getSpoilerText())) {
|
||||
return context.getString(R.string.description_post_cw, status.getSpoilerText());
|
||||
if (!TextUtils.isEmpty(status.getActionable().getSpoilerText())) {
|
||||
return context.getString(R.string.description_post_cw, status.getActionable().getSpoilerText());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class ConversationViewHolder extends StatusBaseViewHolder {
|
|||
if (payloads == null) {
|
||||
TimelineAccount account = status.getAccount();
|
||||
|
||||
setupCollapsedState(statusViewData.isCollapsible(), statusViewData.isCollapsed(), statusViewData.isExpanded(), statusViewData.getSpoilerText(), listener);
|
||||
setupCollapsedState(statusViewData.isCollapsible(), statusViewData.isCollapsed(), statusViewData.isExpanded(), status.getSpoilerText(), listener);
|
||||
|
||||
setDisplayName(account.getDisplayName(), account.getEmojis(), statusDisplayOptions);
|
||||
setUsername(account.getUsername());
|
||||
|
|
|
|||
|
|
@ -201,8 +201,7 @@ public class NotificationHelper {
|
|||
builder.setLargeIcon(accountAvatar);
|
||||
|
||||
// Reply to mention action; RemoteInput is available from KitKat Watch, but buttons are available from Nougat
|
||||
if (body.getType() == Notification.Type.MENTION
|
||||
&& android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (body.getType() == Notification.Type.MENTION) {
|
||||
RemoteInput replyRemoteInput = new RemoteInput.Builder(KEY_REPLY)
|
||||
.setLabel(context.getString(R.string.label_quick_reply))
|
||||
.build();
|
||||
|
|
@ -859,7 +858,7 @@ public class NotificationHelper {
|
|||
if (mutable) {
|
||||
return PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_MUTABLE : 0);
|
||||
} else {
|
||||
return PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||
return PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,15 +103,15 @@ class StatusViewHolder(
|
|||
shouldTrimStatus(viewdata.content),
|
||||
viewState.isCollapsed(viewdata.id, true),
|
||||
viewState.isContentShow(viewdata.id, viewdata.status.sensitive),
|
||||
viewdata.spoilerText
|
||||
viewdata.status.spoilerText
|
||||
)
|
||||
|
||||
if (viewdata.spoilerText.isBlank()) {
|
||||
if (viewdata.status.spoilerText.isBlank()) {
|
||||
setTextVisible(true, viewdata.content, viewdata.status.mentions, viewdata.status.tags, viewdata.status.emojis, adapterHandler)
|
||||
binding.statusContentWarningButton.hide()
|
||||
binding.statusContentWarningDescription.hide()
|
||||
} else {
|
||||
val emojiSpoiler = viewdata.spoilerText.emojify(viewdata.status.emojis, binding.statusContentWarningDescription, statusDisplayOptions.animateEmojis)
|
||||
val emojiSpoiler = viewdata.status.spoilerText.emojify(viewdata.status.emojis, binding.statusContentWarningDescription, statusDisplayOptions.animateEmojis)
|
||||
binding.statusContentWarningDescription.text = emojiSpoiler
|
||||
binding.statusContentWarningDescription.show()
|
||||
binding.statusContentWarningButton.show()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package com.keylesspalace.tusky.service
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Intent
|
||||
import android.service.quicksettings.TileService
|
||||
import com.keylesspalace.tusky.MainActivity
|
||||
|
|
@ -25,8 +24,6 @@ import com.keylesspalace.tusky.components.compose.ComposeActivity
|
|||
* Small Addition that adds in a QuickSettings tile
|
||||
* opens the Compose activity or shows an account selector when multiple accounts are present
|
||||
*/
|
||||
|
||||
@TargetApi(24)
|
||||
class TuskyTileService : TileService() {
|
||||
|
||||
override fun onClick() {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class ListStatusAccessibilityDelegate(
|
|||
val pos = recyclerView.getChildAdapterPosition(host)
|
||||
val status = statusProvider.getStatus(pos) ?: return
|
||||
if (status is StatusViewData.Concrete) {
|
||||
if (status.spoilerText.isNotEmpty()) {
|
||||
if (status.status.spoilerText.isNotEmpty()) {
|
||||
info.addAction(if (status.isExpanded) collapseCwAction else expandCwAction)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.icu.text.BreakIterator
|
||||
import android.text.InputFilter
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
|
|
@ -72,20 +73,10 @@ object SmartLengthInputFilter : InputFilter {
|
|||
if (source[keep].isLetterOrDigit()) {
|
||||
var boundary: Int
|
||||
|
||||
// Android N+ offer a clone of the ICU APIs in Java for better internationalization and
|
||||
// unicode support. Using the ICU version of BreakIterator grants better support for
|
||||
// those without having to add the ICU4J library at a minimum Api trade-off.
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
val iterator = android.icu.text.BreakIterator.getWordInstance()
|
||||
iterator.setText(source.toString())
|
||||
boundary = iterator.following(keep)
|
||||
if (keep - boundary > RUNWAY) boundary = iterator.preceding(keep)
|
||||
} else {
|
||||
val iterator = java.text.BreakIterator.getWordInstance()
|
||||
iterator.setText(source.toString())
|
||||
boundary = iterator.following(keep)
|
||||
if (keep - boundary > RUNWAY) boundary = iterator.preceding(keep)
|
||||
}
|
||||
val iterator = BreakIterator.getWordInstance()
|
||||
iterator.setText(source.toString())
|
||||
boundary = iterator.following(keep)
|
||||
if (keep - boundary > RUNWAY) boundary = iterator.preceding(keep)
|
||||
|
||||
keep = boundary
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.text.Html.TagHandler
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import androidx.core.text.parseAsHtml
|
||||
|
||||
|
|
@ -36,31 +35,3 @@ fun String.parseAsMastodonHtml(tagHandler: TagHandler? = null): Spanned {
|
|||
* most status contents do, so it should be trimmed. */
|
||||
.trimTrailingWhitespace()
|
||||
}
|
||||
|
||||
fun replaceCrashingCharacters(content: Spanned): Spanned {
|
||||
return replaceCrashingCharacters(content as CharSequence) as Spanned
|
||||
}
|
||||
|
||||
fun replaceCrashingCharacters(content: CharSequence): CharSequence? {
|
||||
var replacing = false
|
||||
var builder: SpannableStringBuilder? = null
|
||||
val length = content.length
|
||||
for (index in 0 until length) {
|
||||
val character = content[index]
|
||||
|
||||
// If there are more than one or two, switch to a map
|
||||
if (character == SOFT_HYPHEN) {
|
||||
if (!replacing) {
|
||||
replacing = true
|
||||
builder = SpannableStringBuilder(content, 0, index)
|
||||
}
|
||||
builder!!.append(ASCII_HYPHEN)
|
||||
} else if (replacing) {
|
||||
builder!!.append(character)
|
||||
}
|
||||
}
|
||||
return if (replacing) builder else content
|
||||
}
|
||||
|
||||
private const val SOFT_HYPHEN = '\u00ad'
|
||||
private const val ASCII_HYPHEN = '-'
|
||||
|
|
|
|||
|
|
@ -14,12 +14,10 @@
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
package com.keylesspalace.tusky.viewdata
|
||||
|
||||
import android.os.Build
|
||||
import android.text.Spanned
|
||||
import com.keylesspalace.tusky.entity.Filter
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.util.parseAsMastodonHtml
|
||||
import com.keylesspalace.tusky.util.replaceCrashingCharacters
|
||||
import com.keylesspalace.tusky.util.shouldTrimStatus
|
||||
|
||||
/**
|
||||
|
|
@ -48,17 +46,15 @@ sealed class StatusViewData {
|
|||
override val id: String
|
||||
get() = status.id
|
||||
|
||||
val content: Spanned = status.actionableStatus.content.parseAsMastodonHtml()
|
||||
|
||||
/**
|
||||
* Specifies whether the content of this post is long enough to be automatically
|
||||
* collapsed or if it should show all content regardless.
|
||||
*
|
||||
* @return Whether the post is collapsible or never collapsed.
|
||||
*/
|
||||
val isCollapsible: Boolean
|
||||
|
||||
val content: Spanned
|
||||
val spoilerText: String
|
||||
val username: String
|
||||
val isCollapsible: Boolean = shouldTrimStatus(this.content)
|
||||
|
||||
val actionable: Status
|
||||
get() = status.actionableStatus
|
||||
|
|
@ -76,22 +72,6 @@ sealed class StatusViewData {
|
|||
val rebloggingStatus: Status?
|
||||
get() = if (status.reblog != null) status else null
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT == 23) {
|
||||
// https://github.com/tuskyapp/Tusky/issues/563
|
||||
this.content = replaceCrashingCharacters(status.actionableStatus.content.parseAsMastodonHtml())
|
||||
this.spoilerText =
|
||||
replaceCrashingCharacters(status.actionableStatus.spoilerText).toString()
|
||||
this.username =
|
||||
replaceCrashingCharacters(status.actionableStatus.account.username).toString()
|
||||
} else {
|
||||
this.content = status.actionableStatus.content.parseAsMastodonHtml()
|
||||
this.spoilerText = status.actionableStatus.spoilerText
|
||||
this.username = status.actionableStatus.account.username
|
||||
}
|
||||
this.isCollapsible = shouldTrimStatus(this.content)
|
||||
}
|
||||
|
||||
/** Helper for Java */
|
||||
fun copyWithStatus(status: Status): Concrete {
|
||||
return copy(status = status)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue