Lint fixes
This commit is contained in:
parent
2b1fb436a9
commit
b3dd53a5df
@ -37,7 +37,7 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
|
||||
* A dummy implementation of the {@link ListSelectionListener} interface that does
|
||||
* nothing. Used only when this fragment is not attached to an activity.
|
||||
*/
|
||||
private static ListSelectionListener<Object> dummyCallbacks = plaintext -> {
|
||||
private static final ListSelectionListener<Object> dummyCallbacks = plaintext -> {
|
||||
};
|
||||
/**
|
||||
* The fragment's current callback object, which is notified of list item
|
||||
|
@ -144,11 +144,6 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode) {
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (data != null && data.hasExtra("SCAN_RESULT")) {
|
||||
|
@ -20,7 +20,6 @@ import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Switch;
|
||||
@ -61,17 +60,12 @@ public class CreateAddressActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
final Button cancel = (Button) findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
cancel.setOnClickListener(v -> {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
final Button ok = (Button) findViewById(R.id.do_import);
|
||||
ok.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ok.setOnClickListener(v -> {
|
||||
String addressText = String.valueOf(address.getText()).trim();
|
||||
try {
|
||||
BitmessageAddress bmAddress = new BitmessageAddress(addressText);
|
||||
@ -89,7 +83,6 @@ public class CreateAddressActivity extends AppCompatActivity {
|
||||
} catch (RuntimeException e) {
|
||||
address.setError(getString(R.string.error_illegal_address));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import com.mikepenz.materialize.MaterializeBuilder;
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
public class DetailActivity extends AppCompatActivity {
|
||||
public abstract class DetailActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -31,10 +31,10 @@ public class Identicon extends Drawable {
|
||||
private static final int CENTER_COLUMN = 5;
|
||||
|
||||
private final Paint paint;
|
||||
private int color;
|
||||
private int background;
|
||||
private boolean[][] fields;
|
||||
private boolean chan;
|
||||
private final int color;
|
||||
private final int background;
|
||||
private final boolean[][] fields;
|
||||
private final boolean chan;
|
||||
private final TextPaint textPaint;
|
||||
|
||||
public Identicon(BitmessageAddress input) {
|
||||
|
@ -28,7 +28,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.angads25.filepicker.controller.DialogSelectionListener;
|
||||
import com.github.angads25.filepicker.model.DialogConfigs;
|
||||
import com.github.angads25.filepicker.model.DialogProperties;
|
||||
import com.github.angads25.filepicker.view.FilePickerDialog;
|
||||
@ -61,9 +60,7 @@ public class InputWifFragment extends Fragment {
|
||||
View view = inflater.inflate(R.layout.fragment_import_input, container, false);
|
||||
wifData = (TextView) view.findViewById(R.id.wif_input);
|
||||
|
||||
view.findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
view.findViewById(R.id.next).setOnClickListener(v -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(WIF_DATA, wifData.getText().toString());
|
||||
|
||||
@ -73,7 +70,6 @@ public class InputWifFragment extends Fragment {
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
@ -93,9 +89,7 @@ public class InputWifFragment extends Fragment {
|
||||
properties.extensions = null;
|
||||
FilePickerDialog dialog = new FilePickerDialog(getActivity(), properties);
|
||||
dialog.setTitle(getString(R.string.select_file_title));
|
||||
dialog.setDialogSelectionListener(new DialogSelectionListener() {
|
||||
@Override
|
||||
public void onSelectedFilePaths(String[] files) {
|
||||
dialog.setDialogSelectionListener(files -> {
|
||||
if (files.length > 0) {
|
||||
try (InputStream in = new FileInputStream(files[0])) {
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
@ -114,7 +108,6 @@ public class InputWifFragment extends Fragment {
|
||||
).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
return true;
|
||||
|
@ -130,15 +130,12 @@ public class MessageListFragment extends Fragment implements ListHolder {
|
||||
// Show the dummy content as text in a TextView.
|
||||
FloatingActionButton fab = (FloatingActionButton) rootView.findViewById(R.id
|
||||
.fab_compose_message);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
fab.setOnClickListener(view -> {
|
||||
Intent intent = new Intent(getActivity().getApplicationContext(),
|
||||
ComposeMessageActivity.class);
|
||||
intent.putExtra(ComposeMessageActivity.EXTRA_IDENTITY, Singleton.getIdentity
|
||||
(getActivity()));
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
// touch guard manager (this class is required to suppress scrolling while swipe-dismiss
|
||||
@ -173,7 +170,7 @@ public class MessageListFragment extends Fragment implements ListHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemViewClicked(View v, boolean pinned) {
|
||||
public void onItemViewClicked(View v) {
|
||||
int position = recyclerView.getChildAdapterPosition(v);
|
||||
adapter.setSelectedPosition(position);
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
|
@ -46,9 +46,7 @@ public class SettingsFragment
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
Preference about = findPreference("about");
|
||||
about.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
about.setOnPreferenceClickListener(preference -> {
|
||||
new LibsBuilder()
|
||||
.withActivityTitle(getActivity().getString(R.string.about))
|
||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||
@ -57,16 +55,12 @@ public class SettingsFragment
|
||||
.withAboutDescription(getString(R.string.about_app))
|
||||
.start(getActivity());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Preference status = findPreference("status");
|
||||
status.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
status.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(new Intent(getActivity(), StatusActivity.class));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -69,20 +68,17 @@ public class AddressSelectorAdapter
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public Selectable<BitmessageAddress> data;
|
||||
public CheckBox checkbox;
|
||||
public TextView address;
|
||||
public final CheckBox checkbox;
|
||||
public final TextView address;
|
||||
|
||||
private ViewHolder(View v) {
|
||||
super(v);
|
||||
checkbox = (CheckBox) v.findViewById(R.id.checkbox);
|
||||
address = (TextView) v.findViewById(R.id.address);
|
||||
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (data != null) {
|
||||
data.selected = isChecked;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ public class SwipeableMessageAdapter
|
||||
|
||||
private List<Plaintext> data = Collections.emptyList();
|
||||
private EventListener eventListener;
|
||||
private View.OnClickListener itemViewOnClickListener;
|
||||
private View.OnClickListener swipeableViewContainerOnClickListener;
|
||||
private final View.OnClickListener itemViewOnClickListener;
|
||||
private final View.OnClickListener swipeableViewContainerOnClickListener;
|
||||
|
||||
private Label label;
|
||||
private int selectedPosition;
|
||||
@ -75,12 +75,12 @@ public class SwipeableMessageAdapter
|
||||
|
||||
void onItemArchived(Plaintext item);
|
||||
|
||||
void onItemViewClicked(View v, boolean pinned);
|
||||
void onItemViewClicked(View v);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
static class ViewHolder extends AbstractSwipeableItemViewHolder {
|
||||
public FrameLayout container;
|
||||
public final FrameLayout container;
|
||||
public final ImageView avatar;
|
||||
public final TextView sender;
|
||||
public final TextView subject;
|
||||
@ -102,18 +102,8 @@ public class SwipeableMessageAdapter
|
||||
}
|
||||
|
||||
public SwipeableMessageAdapter() {
|
||||
itemViewOnClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onItemViewClick(v);
|
||||
}
|
||||
};
|
||||
swipeableViewContainerOnClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onSwipeableViewContainerClick(v);
|
||||
}
|
||||
};
|
||||
itemViewOnClickListener = this::onItemViewClick;
|
||||
swipeableViewContainerOnClickListener = this::onSwipeableViewContainerClick;
|
||||
|
||||
// SwipeableItemAdapter requires stable ID, and also
|
||||
// have to implement the getItemId() method appropriately.
|
||||
@ -127,14 +117,14 @@ public class SwipeableMessageAdapter
|
||||
|
||||
private void onItemViewClick(View v) {
|
||||
if (eventListener != null) {
|
||||
eventListener.onItemViewClicked(v, true); // pinned
|
||||
eventListener.onItemViewClicked(v);
|
||||
}
|
||||
}
|
||||
|
||||
private void onSwipeableViewContainerClick(View v) {
|
||||
if (eventListener != null) {
|
||||
eventListener.onItemViewClicked(
|
||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v), false); // not pinned
|
||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@ package ch.dissem.apps.abit.dialog;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
@ -61,9 +60,7 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
getDialog().setTitle(R.string.add_identity);
|
||||
View view = inflater.inflate(R.layout.dialog_add_identity, container, false);
|
||||
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.radioGroup);
|
||||
view.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
view.findViewById(R.id.ok).setOnClickListener(v -> {
|
||||
final Context ctx = getActivity().getBaseContext();
|
||||
switch (radioGroup.getCheckedRadioButtonId()) {
|
||||
case R.id.create_identity:
|
||||
@ -102,15 +99,8 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
return;
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.dismiss)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.dismiss).setOnClickListener(v -> dismiss());
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -123,9 +113,7 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.add_chan)
|
||||
.setView(dialogView)
|
||||
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
|
||||
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase);
|
||||
Toast.makeText(ctx, R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
@ -150,7 +138,6 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
}
|
||||
}
|
||||
}.execute(passphrase.getText().toString());
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
|
@ -29,6 +29,7 @@ import ch.dissem.bitmessage.BitmessageContext;
|
||||
public class WifiReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context ctx, Intent intent) {
|
||||
if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
|
||||
if (Preferences.isWifiOnly(ctx)) {
|
||||
BitmessageContext bmc = Singleton.getBitmessageContext(ctx);
|
||||
|
||||
@ -37,6 +38,7 @@ public class WifiReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isConnectedToMeteredNetwork(Context ctx) {
|
||||
NetworkInfo netInfo = getNetworkInfo(ctx);
|
||||
|
@ -31,7 +31,7 @@ import ch.dissem.apps.abit.R;
|
||||
public class ErrorNotification extends AbstractNotification {
|
||||
public static final int ERROR_NOTIFICATION_ID = 4;
|
||||
|
||||
private NotificationCompat.Builder builder;
|
||||
private final NotificationCompat.Builder builder;
|
||||
|
||||
public ErrorNotification(Context ctx) {
|
||||
super(ctx);
|
||||
|
@ -17,14 +17,12 @@
|
||||
package ch.dissem.apps.abit.pow;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import ch.dissem.apps.abit.service.Singleton;
|
||||
import ch.dissem.apps.abit.synchronization.SyncAdapter;
|
||||
@ -52,21 +50,16 @@ public class ServerPowEngine implements ProofOfWorkEngine, InternalContext
|
||||
|
||||
public ServerPowEngine(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
pool = Executors.newCachedThreadPool(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(@NonNull Runnable r) {
|
||||
pool = Executors.newCachedThreadPool(r -> {
|
||||
Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculateNonce(final byte[] initialHash, final byte[] target, Callback callback) {
|
||||
pool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pool.execute(() -> {
|
||||
BitmessageAddress identity = Singleton.getIdentity(ctx);
|
||||
if (identity == null) throw new RuntimeException("No Identity for calculating POW");
|
||||
|
||||
@ -86,7 +79,6 @@ public class ServerPowEngine implements ProofOfWorkEngine, InternalContext
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -169,15 +169,11 @@ public class AndroidAddressRepository implements AddressRepository {
|
||||
|
||||
@Override
|
||||
public void save(BitmessageAddress address) {
|
||||
try {
|
||||
if (exists(address)) {
|
||||
update(address);
|
||||
} else {
|
||||
insert(address);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean exists(BitmessageAddress address) {
|
||||
@ -191,7 +187,7 @@ public class AndroidAddressRepository implements AddressRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private void update(BitmessageAddress address) throws IOException {
|
||||
private void update(BitmessageAddress address) {
|
||||
try {
|
||||
SQLiteDatabase db = sql.getWritableDatabase();
|
||||
// Create a new map of values, where column names are the keys
|
||||
@ -224,7 +220,7 @@ public class AndroidAddressRepository implements AddressRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private void insert(BitmessageAddress address) throws IOException {
|
||||
private void insert(BitmessageAddress address) {
|
||||
try {
|
||||
SQLiteDatabase db = sql.getWritableDatabase();
|
||||
// Create a new map of values, where column names are the keys
|
||||
|
@ -275,14 +275,12 @@ public class AndroidMessageRepository extends AbstractMessageRepository {
|
||||
db.setTransactionSuccessful();
|
||||
} catch (SQLiteConstraintException e) {
|
||||
LOG.trace(e.getMessage(), e);
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
private void insert(SQLiteDatabase db, Plaintext message) throws IOException {
|
||||
private void insert(SQLiteDatabase db, Plaintext message) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_IV, message.getInventoryVector() == null ? null : message
|
||||
.getInventoryVector().getHash());
|
||||
@ -302,7 +300,7 @@ public class AndroidMessageRepository extends AbstractMessageRepository {
|
||||
message.setId(id);
|
||||
}
|
||||
|
||||
private void update(SQLiteDatabase db, Plaintext message) throws IOException {
|
||||
private void update(SQLiteDatabase db, Plaintext message) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_IV, message.getInventoryVector() == null ? null : message
|
||||
.getInventoryVector().getHash());
|
||||
|
@ -27,10 +27,10 @@ import ch.dissem.apps.abit.util.Assets;
|
||||
*/
|
||||
public class SqlHelper extends SQLiteOpenHelper {
|
||||
// If you change the database schema, you must increment the database version.
|
||||
public static final int DATABASE_VERSION = 5;
|
||||
public static final String DATABASE_NAME = "jabit.db";
|
||||
private static final int DATABASE_VERSION = 5;
|
||||
private static final String DATABASE_NAME = "jabit.db";
|
||||
|
||||
protected final Context ctx;
|
||||
private final Context ctx;
|
||||
|
||||
public SqlHelper(Context ctx) {
|
||||
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
@ -65,7 +65,7 @@ public class SqlHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
}
|
||||
|
||||
protected void executeMigration(SQLiteDatabase db, String name) {
|
||||
private void executeMigration(SQLiteDatabase db, String name) {
|
||||
for (String statement : Assets.readSqlStatements(ctx, "db/migration/" + name + ".sql")) {
|
||||
db.execSQL(statement);
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ import static ch.dissem.apps.abit.notification.ProofOfWorkNotification.ONGOING_N
|
||||
*/
|
||||
public class ProofOfWorkService extends Service {
|
||||
// Object to use as a thread-safe lock
|
||||
private static ProofOfWorkEngine engine = new MultiThreadedPOWEngine();
|
||||
private static boolean calculating;
|
||||
private static final ProofOfWorkEngine engine = new MultiThreadedPOWEngine();
|
||||
private static final Queue<PowItem> queue = new LinkedList<>();
|
||||
private static boolean calculating;
|
||||
private ProofOfWorkNotification notification;
|
||||
|
||||
@Override
|
||||
|
@ -38,14 +38,14 @@ public class ServicePowEngine implements ProofOfWorkEngine {
|
||||
private final Context ctx;
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private Queue<PowItem> queue = new LinkedList<>();
|
||||
private final Queue<PowItem> queue = new LinkedList<>();
|
||||
private PowBinder service;
|
||||
|
||||
public ServicePowEngine(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
private ServiceConnection connection = new ServiceConnection() {
|
||||
private final ServiceConnection connection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
synchronized (lock) {
|
||||
|
@ -20,9 +20,6 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user