diff --git a/app/build.gradle b/app/build.gradle index 723ee71a4..42c183981 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,8 +28,8 @@ android { applicationId "io.github.feelfreelinux.wykopmobilny" minSdkVersion 17 targetSdkVersion 27 - versionCode 25 - versionName "0.5.3.2" + versionCode 26 + versionName "0.5.4" def credentialsPropertiesFile = rootProject.file("credentials.properties") def credentialsProperties = new Properties() diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/PMMessageViewHolder.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/PMMessageViewHolder.kt index 3794201f4..59ae58bec 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/PMMessageViewHolder.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/PMMessageViewHolder.kt @@ -29,7 +29,7 @@ class PMMessageViewHolder(val view: View, date.text = context.getString(R.string.date_with_user_app, message.date, message.app) } - body.prepareBody(message.body, { linkHandlerApi.handleUrl(it) }) + body.prepareBody(message.body, { linkHandlerApi.handleUrl(it) }, null, settingsPreferencesApi.openSpoilersDialog) embedImage.forceDisableMinimizedMode = true embedImage.setEmbed(message.embed, settingsPreferencesApi, navigatorApi) } diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/notificationslist/BaseNotificationsListFragment.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/notificationslist/BaseNotificationsListFragment.kt index da6bc3fde..64e9a28ee 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/notificationslist/BaseNotificationsListFragment.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/notificationslist/BaseNotificationsListFragment.kt @@ -64,7 +64,7 @@ abstract class BaseNotificationsListFragment : BaseFragment(), NotificationsList if (notifications.isNotEmpty()) { loadingView.isVisible = false swiperefresh.isRefreshing = false - notificationAdapter.addData(notifications.filterNot { notificationAdapter.data.contains(it) }, shouldClearAdapter) + notificationAdapter.addData(if (!shouldClearAdapter) notifications.filterNot { notificationAdapter.data.contains(it) } else notifications, shouldClearAdapter) } else notificationAdapter.disableLoading() } diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/EntryWidget.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/EntryWidget.kt index b05c6ea3b..3d0bab8be 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/EntryWidget.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/EntryWidget.kt @@ -32,6 +32,7 @@ class EntryWidget(context: Context, attrs: AttributeSet) : CardView(context, att private lateinit var userManagerApi: UserManagerApi private lateinit var presenter: EntryPresenter private lateinit var entry: Entry + private lateinit var settingsPreferencesApi : SettingsPreferencesApi private lateinit var votersDialogListener : (List) -> Unit var shouldEnableClickListener = true @@ -59,6 +60,7 @@ class EntryWidget(context: Context, attrs: AttributeSet) : CardView(context, att presenter = entryPresenter userManagerApi = userManager voteButton.setup(userManager) + settingsPreferencesApi = settingsApi presenter.subscribe(this) this.entry = entry presenter.entryId = entry.id @@ -114,7 +116,7 @@ class EntryWidget(context: Context, attrs: AttributeSet) : CardView(context, att private fun setupBody() { if (entry.body.isNotEmpty()) { entryContentTextView.isVisible = true - entryContentTextView.prepareBody(entry.body, { presenter.handleLink(it) }, { if (shouldEnableClickListener) presenter.openDetails(true) }) + entryContentTextView.prepareBody(entry.body, { presenter.handleLink(it) }, { if (shouldEnableClickListener) presenter.openDetails(true) }, settingsPreferencesApi.openSpoilersDialog) } else entryContentTextView.isVisible = false if (entry.survey != null) { diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/comment/CommentWidget.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/comment/CommentWidget.kt index 49ed0d544..8470ced20 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/comment/CommentWidget.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/entry/comment/CommentWidget.kt @@ -42,7 +42,7 @@ class CommentWidget : CardView, CommentView { lateinit var presenter : CommentPresenter private lateinit var userManagerApi: UserManagerApi private lateinit var votersDialogListener : (List) -> Unit - + lateinit var settingsPreferencesApi : SettingsPreferencesApi init { View.inflate(context, R.layout.entry_comment_layout, this) isClickable = true @@ -52,8 +52,9 @@ class CommentWidget : CardView, CommentView { setBackgroundResource(typedValue.resourceId) } - fun setCommentData(entryComment: EntryComment, userManager : UserManagerApi, settingsPreferencesApi: SettingsPreferencesApi, commentPresenter: CommentPresenter) { + fun setCommentData(entryComment: EntryComment, userManager : UserManagerApi, settingsApi: SettingsPreferencesApi, commentPresenter: CommentPresenter) { this.comment = entryComment + settingsPreferencesApi = settingsApi presenter = commentPresenter userManagerApi = userManager commentPresenter.commentId = entryComment.id @@ -103,7 +104,7 @@ class CommentWidget : CardView, CommentView { replyTextView.setOnClickListener { addReceiver() } if (comment.body.isNotEmpty()) { entryContentTextView.isVisible = true - entryContentTextView.prepareBody(comment.body, { presenter.handleLink(it) }) + entryContentTextView.prepareBody(comment.body, { presenter.handleLink(it) }, null, settingsPreferencesApi.openSpoilersDialog) } else entryContentTextView.isVisible = false } diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/link/comment/LinkCommentWidget.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/link/comment/LinkCommentWidget.kt index cd5e1d53e..48ecd0af6 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/link/comment/LinkCommentWidget.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/widgets/link/comment/LinkCommentWidget.kt @@ -23,7 +23,7 @@ import kotlinx.android.synthetic.main.link_comment_layout.view.* import kotlinx.android.synthetic.main.link_comment_menu_bottomsheet.view.* import kotlin.math.absoluteValue -class LinkCommentWidget(context: Context, attrs: AttributeSet) : CardView(context, attrs), URLClickedListener, LinkCommentView { +class LinkCommentWidget(context: Context, attrs: AttributeSet) : CardView(context, attrs), LinkCommentView { lateinit var comment : LinkComment lateinit var presenter : LinkCommentPresenter lateinit var settingsApi : SettingsPreferencesApi @@ -65,7 +65,7 @@ class LinkCommentWidget(context: Context, attrs: AttributeSet) : CardView(contex private fun setupBody() { commentImageView.setEmbed(comment.embed, settingsApi, presenter.newNavigatorApi, comment.isNsfw) comment.body?.let { - commentContentTextView.prepareBody(comment.body!!, this) + commentContentTextView.prepareBody(comment.body!!, { presenter.handleUrl(it) }, null, settingsApi.openSpoilersDialog) } collapseButton.setOnClickListener { commentContentTextView.isVisible = false @@ -102,10 +102,6 @@ class LinkCommentWidget(context: Context, attrs: AttributeSet) : CardView(contex } - override fun handleUrl(url: String) { - presenter.handleUrl(url) - } - private fun setupButtons() { plusButton.setup(userManagerApi) plusButton.text = comment.voteCountPlus.toString() diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/SettingsPreferences.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/SettingsPreferences.kt index 3e2380eec..e3b1739a5 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/SettingsPreferences.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/SettingsPreferences.kt @@ -13,6 +13,7 @@ interface SettingsPreferencesApi { var showNotifications : Boolean var showMinifiedImages : Boolean var cutImages : Boolean + var openSpoilersDialog : Boolean var cutImageProportion : Int } @@ -28,5 +29,6 @@ class SettingsPreferences(context : Context) : Preferences(context, true), Setti override var showMinifiedImages by booleanPref(defaultValue = false) override var cutImages by booleanPref(defaultValue = true) override var cutImageProportion by intPref(defaultValue = 60) + override var openSpoilersDialog by booleanPref(defaultValue = true) override var showNotifications by booleanPref(defaultValue = true) } \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/BetterLinkMovementMethod.java b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/BetterLinkMovementMethod.java index d8a5b1069..7f15d0502 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/BetterLinkMovementMethod.java +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/BetterLinkMovementMethod.java @@ -52,7 +52,7 @@ public interface OnLinkClickListener { * @param url The clicked URL. * @return True if this click was handled. False to let Android handle the URL. */ - boolean onClick(TextView textView, String url); + boolean onClick(TextView textView, ClickableSpanWithText url); } public interface OnTextClickListener { @@ -404,7 +404,7 @@ protected void removeLongPressCallback(TextView textView) { protected void dispatchUrlClick(TextView textView, ClickableSpan clickableSpan) { ClickableSpanWithText clickableSpanWithText = ClickableSpanWithText.ofSpan(textView, clickableSpan); - boolean handled = onLinkClickListener != null && onLinkClickListener.onClick(textView, clickableSpanWithText.text()); + boolean handled = onLinkClickListener != null && onLinkClickListener.onClick(textView, clickableSpanWithText); if (!handled) { // Let Android handle this click. diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/TextViewExtensions.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/TextViewExtensions.kt index 0ca4e3dfa..0fb5d8a96 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/TextViewExtensions.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/textview/TextViewExtensions.kt @@ -1,9 +1,15 @@ package io.github.feelfreelinux.wykopmobilny.utils.textview +import android.text.ParcelableSpan +import android.text.Spannable +import android.text.SpannableString import android.text.SpannableStringBuilder +import android.text.style.ClickableSpan import android.widget.TextView import io.github.feelfreelinux.wykopmobilny.ui.dialogs.createAlertBuilder +import io.github.feelfreelinux.wykopmobilny.utils.printout import java.net.URLDecoder +import java.sql.Struct fun TextView.prepareBody(html: String, listener : URLClickedListener) { @@ -11,20 +17,15 @@ fun TextView.prepareBody(html: String, listener : URLClickedListener) { val method = BetterLinkMovementMethod.linkifyHtml(this) method.setOnLinkClickListener({ textView, url -> - if (url.startsWith("spoiler:")) { - val text = url.substringAfter("spoiler:") - context.createAlertBuilder().apply { - setTitle("Spoiler") - setMessage(URLDecoder.decode(text, "UTF-8")) - setPositiveButton(android.R.string.ok, null) - create().show() - } - } else listener.handleUrl(url) + if (url.text().startsWith("spoiler:")) { + val text = url.text().substringAfter("spoiler:") + + } else listener.handleUrl(url.text()) true }) } -fun TextView.prepareBody(html: String, urlClickListener : (String) -> Unit, clickListener : (() -> Unit)? = null) { +fun TextView.prepareBody(html: String, urlClickListener : (String) -> Unit, clickListener : (() -> Unit)? = null, shouldOpenSpoilerDialog : Boolean) { text = SpannableStringBuilder(html.toSpannable()) val method = BetterLinkMovementMethod.linkifyHtml(this) clickListener?.let { @@ -34,15 +35,39 @@ fun TextView.prepareBody(html: String, urlClickListener : (String) -> Unit, clic } method.setOnLinkClickListener({ _, url -> - if (url.startsWith("spoiler:")) { - val text = url.substringAfter("spoiler:") - context.createAlertBuilder().apply { - setTitle("Spoiler") - setMessage(URLDecoder.decode(text, "UTF-8")) - setPositiveButton(android.R.string.ok, null) - create().show() + if (url.text().startsWith("spoiler:")) { + if (!shouldOpenSpoilerDialog) { + openSpoilers(url.span(), url.text()) + } else { + context.createAlertBuilder().apply { + setTitle("Spoiler") + setMessage(URLDecoder.decode(url.text().substringAfter("spoiler:"), "UTF-8")) + setPositiveButton(android.R.string.ok, null) + create().show() + } } - } else urlClickListener(url) + } else urlClickListener(url.text()) true }) +} + +fun TextView.openSpoilers(span : ClickableSpan, rawText : String) { + val spoilerText = URLDecoder.decode(rawText.substringAfter("spoiler:"), "UTF-8").toSpannable() + val textBuilder = (text as SpannableString) + val start = textBuilder.getSpanStart(span) + val end = textBuilder.getSpanEnd(span) + val ssb = SpannableStringBuilder(textBuilder.replaceRange(start, end, spoilerText)) + textBuilder.getSpans(0, textBuilder.length, ParcelableSpan::class.java).forEach { + val spanStart = textBuilder.getSpanStart(it) + val spanEnd = textBuilder.getSpanEnd(it) + val totalStart = if (spanStart < start) spanStart else spanStart - 15 + spoilerText.length + val totalEnd = if (spanEnd < end) spanEnd else spanEnd - 15 + spoilerText.length + if (span != it) ssb.setSpan(it, totalStart, totalEnd, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) + } + + spoilerText.getSpans(0, spoilerText.length, ParcelableSpan::class.java).forEach { + val spanStart = spoilerText.getSpanStart(it) + ssb.setSpan(it, start + spanStart, end + spanStart, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) + } + text = ssb } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 942927b35..84c20113e 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,7 +6,7 @@ Wygląd Styl nocny Domyślny ekran aplikacji - Domyślny ekran w gorących wpisach + Domyślny ekran w mirkoblogu Powiadomienia Włącz powiadomienia Częstotliwość sprawdzania @@ -166,6 +166,7 @@ Hity tygodnia Hity miesiąca Hity roku + Otwieraj spoilery w okienku Hity miesiąca (%1$d/%2$d) Hity roku (%1$d) diff --git a/app/src/main/res/xml/app_preferences.xml b/app/src/main/res/xml/app_preferences.xml index 06dda36ba..052793d2a 100755 --- a/app/src/main/res/xml/app_preferences.xml +++ b/app/src/main/res/xml/app_preferences.xml @@ -26,6 +26,12 @@ android:entries="@array/preferences_hot_screen" android:entryValues="@array/preferences_hot_screen_values" android:defaultValue="newest"/> + + +