This commit is contained in:
Ryan ZHAO
2021-02-01 15:01:06 +11:00
parent a34a18f5f1
commit 2db567144d
20 changed files with 22 additions and 24 deletions

View File

@@ -0,0 +1,36 @@
package org.session.libsession.utilities;
import android.os.Handler;
/**
* A class that will throttle the number of runnables executed to be at most once every specified
* interval. However, it could be longer if events are published consistently.
*
* Useful for performing actions in response to rapid user input, such as inputting text, where you
* don't necessarily want to perform an action after <em>every</em> input.
*
* See http://rxmarbles.com/#debounce
*/
public class Debouncer {
private final Handler handler;
private final long threshold;
/**
* @param threshold Only one runnable will be executed via {@link #publish(Runnable)} every
* {@code threshold} milliseconds.
*/
public Debouncer(long threshold) {
this.handler = new Handler();
this.threshold = threshold;
}
public void publish(Runnable runnable) {
handler.removeCallbacksAndMessages(null);
handler.postDelayed(runnable, threshold);
}
public void clear() {
handler.removeCallbacksAndMessages(null);
}
}

View File

@@ -0,0 +1,45 @@
package org.session.libsession.utilities;
import android.os.Handler;
/**
* A class that will throttle the number of runnables executed to be at most once every specified
* interval.
*
* Useful for performing actions in response to rapid user input where you want to take action on
* the initial input but prevent follow-up spam.
*
* This is different from {@link Debouncer} in that it will run the first runnable immediately
* instead of waiting for input to die down.
*
* See http://rxmarbles.com/#throttle
*/
public class Throttler {
private static final int WHAT = 8675309;
private final Handler handler;
private final long threshold;
/**
* @param threshold Only one runnable will be executed via {@link #publish(Runnable)} every
* {@code threshold} milliseconds.
*/
public Throttler(long threshold) {
this.handler = new Handler();
this.threshold = threshold;
}
public void publish(Runnable runnable) {
if (handler.hasMessages(WHAT)) {
return;
}
runnable.run();
handler.sendMessageDelayed(handler.obtainMessage(WHAT), threshold);
}
public void clear() {
handler.removeCallbacksAndMessages(null);
}
}

View File

@@ -0,0 +1,26 @@
package org.session.libsession.utilities.color.spans;
import androidx.annotation.NonNull;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
public class CenterAlignedRelativeSizeSpan extends MetricAffectingSpan {
private final float relativeSize;
public CenterAlignedRelativeSizeSpan(float relativeSize) {
this.relativeSize = relativeSize;
}
@Override
public void updateMeasureState(@NonNull TextPaint p) {
updateDrawState(p);
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setTextSize(tp.getTextSize() * relativeSize);
tp.baselineShift += (int) (tp.ascent() * relativeSize) / 4;
}
}

View File

@@ -0,0 +1,44 @@
package org.session.libsession.utilities.task;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import java.lang.ref.WeakReference;
public abstract class ProgressDialogAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private final WeakReference<Context> contextReference;
private ProgressDialog progress;
private final String title;
private final String message;
public ProgressDialogAsyncTask(@NonNull Context context, @NonNull String title, @NonNull String message) {
super();
this.contextReference = new WeakReference<>(context);
this.title = title;
this.message = message;
}
public ProgressDialogAsyncTask(@NonNull Context context, int title, int message) {
this(context, context.getString(title), context.getString(message));
}
@Override
protected void onPreExecute() {
final Context context = contextReference.get();
if (context != null) progress = ProgressDialog.show(context, title, message, true);
}
@Override
protected void onPostExecute(Result result) {
if (progress != null) progress.dismiss();
}
protected @NonNull Context getContext() {
return contextReference.get();
}
}

View File

@@ -0,0 +1,94 @@
package org.session.libsession.utilities.task;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
public abstract class SnackbarAsyncTask<Params>
extends AsyncTask<Params, Void, Void>
implements View.OnClickListener
{
private final View view;
private final String snackbarText;
private final String snackbarActionText;
private final int snackbarActionColor;
private final int snackbarDuration;
private final boolean showProgress;
private @Nullable Params reversibleParameter;
private @Nullable ProgressDialog progressDialog;
public SnackbarAsyncTask(View view,
String snackbarText,
String snackbarActionText,
int snackbarActionColor,
int snackbarDuration,
boolean showProgress)
{
this.view = view;
this.snackbarText = snackbarText;
this.snackbarActionText = snackbarActionText;
this.snackbarActionColor = snackbarActionColor;
this.snackbarDuration = snackbarDuration;
this.showProgress = showProgress;
}
@Override
protected void onPreExecute() {
if (this.showProgress) this.progressDialog = ProgressDialog.show(view.getContext(), "", "", true);
else this.progressDialog = null;
}
@SafeVarargs
@Override
protected final Void doInBackground(Params... params) {
this.reversibleParameter = params != null && params.length > 0 ?params[0] : null;
executeAction(reversibleParameter);
return null;
}
@Override
protected void onPostExecute(Void result) {
if (this.showProgress && this.progressDialog != null) {
this.progressDialog.dismiss();
this.progressDialog = null;
}
Snackbar.make(view, snackbarText, snackbarDuration)
.setAction(snackbarActionText, this)
.setActionTextColor(snackbarActionColor)
.show();
}
@Override
public void onClick(View v) {
new AsyncTask<Void, Void, Void>() {
@Override
protected void onPreExecute() {
if (showProgress) progressDialog = ProgressDialog.show(view.getContext(), "", "", true);
else progressDialog = null;
}
@Override
protected Void doInBackground(Void... params) {
reverseAction(reversibleParameter);
return null;
}
@Override
protected void onPostExecute(Void result) {
if (showProgress && progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
protected abstract void executeAction(@Nullable Params parameter);
protected abstract void reverseAction(@Nullable Params parameter);
}