Skip to content

Commit

Permalink
[New Designs] Update Test overview to remove run button and implement…
Browse files Browse the repository at this point in the history
  • Loading branch information
aanorbel authored Nov 24, 2023
1 parent 997840c commit 0bf531c
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import org.openobservatory.ooniprobe.R;
import org.openobservatory.ooniprobe.common.PreferenceManager;
import org.openobservatory.ooniprobe.common.ReadMorePlugin;
import org.openobservatory.ooniprobe.databinding.ActivityOverviewBinding;
import org.openobservatory.ooniprobe.model.database.Result;
import org.openobservatory.ooniprobe.test.suite.AbstractSuite;
Expand Down Expand Up @@ -50,11 +51,11 @@ public static Intent newIntent(Context context, AbstractSuite testSuite) {
setTitle(testSuite.getTitle());
binding.icon.setImageResource(testSuite.getIcon());
binding.customUrl.setVisibility(testSuite.getName().equals(WebsitesSuite.NAME) ? View.VISIBLE : View.GONE);
if(testSuite.isTestEmpty(preferenceManager)){
binding.run.setAlpha(0.5F);
binding.run.setEnabled(false);
}
Markwon markwon = Markwon.builder(this).build();
Markwon markwon = Markwon.builder(this)
.usePlugin(new ReadMorePlugin(
getString(R.string.OONIRun_ReadMore),
getString(R.string.OONIRun_ReadLess))
).build();
if (testSuite.getName().equals(ExperimentalSuite.NAME)) {
String experimentalLinks =
"\n\n* [STUN Reachability](https://github.com/ooni/spec/blob/master/nettests/ts-025-stun-reachability.md)" +
Expand All @@ -63,11 +64,13 @@ public static Intent newIntent(Context context, AbstractSuite testSuite) {
"\n\n* [Tor Snowflake](https://ooni.org/nettest/tor-snowflake/) "+ String.format(" ( %s )",getString(R.string.Settings_TestOptions_LongRunningTest))+
"\n\n* [Vanilla Tor](https://github.com/ooni/spec/blob/master/nettests/ts-016-vanilla-tor.md) " + String.format(" ( %s )",getString(R.string.Settings_TestOptions_LongRunningTest));
markwon.setMarkdown(binding.desc, getString(testSuite.getDesc1(), experimentalLinks));
if (TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL)
binding.desc.setTextDirection(View.TEXT_DIRECTION_RTL);
if (TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL) {
binding.desc.setTextDirection(View.TEXT_DIRECTION_RTL);
}
}
else
markwon.setMarkdown(binding.desc, getString(testSuite.getDesc1()));
else {
markwon.setMarkdown(binding.desc, getString(testSuite.getDesc1()));
}
Result lastResult = Result.getLastResult(testSuite.getName());
if (lastResult == null)
binding.lastTime.setText(R.string.Dashboard_Overview_LastRun_Never);
Expand All @@ -78,7 +81,6 @@ public static Intent newIntent(Context context, AbstractSuite testSuite) {
}

private void setUpOnCLickListeners() {
binding.run.setOnClickListener(view -> onRunClick());
binding.customUrl.setOnClickListener(view -> customUrlClick());
}

Expand All @@ -95,12 +97,6 @@ public boolean onSupportNavigateUp() {
return true;
}

void onRunClick() {
if(!testSuite.isTestEmpty(preferenceManager)){
RunningActivity.runAsForegroundService(this, testSuite.asArray(), this::bindTestService, preferenceManager);
}
}

void customUrlClick() {
startActivity(new Intent(this, CustomWebsiteActivity.class));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package org.openobservatory.ooniprobe.common

import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.ClickableSpan
import android.text.style.ReplacementSpan
import android.view.View
import android.widget.TextView
import io.noties.markwon.AbstractMarkwonPlugin


/**
* Read more plugin based on text length.
* @see <a href="https://github.com/noties/Markwon/blob/v4.6.2/app-sample/src/main/java/io/noties/markwon/app/samples/ReadMorePluginSample.java#L208C2-L208C2">ReadMorePluginSample</a>
*/
class ReadMorePlugin(private val labelMore: String, private val labelLess: String) : AbstractMarkwonPlugin() {
private val maxLength = 150

override fun afterSetText(textView: TextView) {
val text = textView.text
if (text.length < maxLength) {
// everything is OK, no need to ellipsize)
return
}
val breakAt = breakTextAt(text, 0, maxLength)
val cs = createCollapsedString(text, 0, breakAt)
textView.text = cs
}

private fun createCollapsedString(text: CharSequence, start: Int, end: Int): CharSequence {
val builder = SpannableStringBuilder(text, start, end)
val spans = builder.getSpans(
0, builder.length,
ReplacementSpan::class.java
)
if (spans != null) {
for (span in spans) {
builder.removeSpan(span)
}
}


trim(builder)
val fullText = createFullText(text, builder)
builder.append(" ...")
val length = builder.length
builder.append("\n\n")
builder.append(labelMore)
builder.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
(widget as TextView).text = fullText
}
}, length, builder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return builder
}

private fun createFullText(text: CharSequence, collapsedText: CharSequence): CharSequence {
val fullText: CharSequence
val builder = SpannableStringBuilder(text)
builder.append(' ')
val length = builder.length
builder.append("\n\n")
builder.append(labelLess)
builder.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
(widget as TextView).text = collapsedText
}
}, length, builder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
fullText = builder

return fullText
}

companion object {
private fun trim(builder: SpannableStringBuilder) {

// NB! tables use `\u00a0` (non breaking space) which is not reported as white-space
var c: Char
run {
var i = 0
val length = builder.length
while (i < length) {
c = builder[i]
if (!Character.isWhitespace(c) && c != '\u00a0') {
if (i > 0) {
builder.replace(0, i, "")
}
break
}
i++
}
}
for (i in builder.length - 1 downTo 0) {
c = builder[i]
if (!Character.isWhitespace(c) && c != '\u00a0') {
if (i < builder.length - 1) {
builder.replace(i, builder.length, "")
}
break
}
}
}

// depending on your locale these can be different
// There is a BreakIterator in Android, but it is not reliable, still theoretically
// it should work better than hand-written and hardcoded rules
private fun breakTextAt(text: CharSequence, start: Int, max: Int): Int {
var last = start

// no need to check for _start_ (anyway will be ignored)
for (i in start + max - 1 downTo start + 1) {
val c = text[i]
if (Character.isWhitespace(c) || c == '.' || c == ',' || c == '!' || c == '?') {
// include this special character
last = i - 1
break
}
}
return if (last <= start) {
// when used in subSequence last index is exclusive,
// so given max=150 would result in 0-149 subSequence
start + max
} else last
}
}
}
Loading

0 comments on commit 0bf531c

Please sign in to comment.