Add reports

This commit is contained in:
Thomas 2022-11-12 17:14:58 +01:00
parent d7f58dab36
commit 2d87254ac0
11 changed files with 297 additions and 34 deletions

View file

@ -191,6 +191,11 @@
android:name=".activities.AdminAccountActivity" android:name=".activities.AdminAccountActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/account" /> android:label="@string/account" />
<activity
android:name=".activities.AccountReportActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/account"
android:theme="@style/AppThemeBar" />
<activity <activity
android:name=".activities.AdminReportActivity" android:name=".activities.AdminReportActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"

View file

@ -19,6 +19,7 @@ import android.app.Activity;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.Toast; import android.widget.Toast;
@ -31,7 +32,7 @@ import java.util.ArrayList;
import app.fedilab.android.R; import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.AdminAccount; import app.fedilab.android.client.entities.api.AdminAccount;
import app.fedilab.android.client.entities.api.Report; import app.fedilab.android.client.entities.api.AdminReport;
import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.databinding.ActivityAdminReportBinding; import app.fedilab.android.databinding.ActivityAdminReportBinding;
import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.Helper;
@ -44,7 +45,7 @@ public class AccountReportActivity extends BaseActivity {
private String account_id; private String account_id;
private Report report; private AdminReport report;
private ActivityAdminReportBinding binding; private ActivityAdminReportBinding binding;
private AdminVM adminVM; private AdminVM adminVM;
@ -66,7 +67,7 @@ public class AccountReportActivity extends BaseActivity {
if (b != null) { if (b != null) {
account_id = b.getString(Helper.ARG_ACCOUNT_ID, null); account_id = b.getString(Helper.ARG_ACCOUNT_ID, null);
targeted_account = (AdminAccount) b.getSerializable(Helper.ARG_ACCOUNT); targeted_account = (AdminAccount) b.getSerializable(Helper.ARG_ACCOUNT);
report = (Report) b.getSerializable(Helper.ARG_REPORT); report = (AdminReport) b.getSerializable(Helper.ARG_REPORT);
} }
@ -330,6 +331,15 @@ public class AccountReportActivity extends BaseActivity {
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
public enum actionType { public enum actionType {
ENABLE, ENABLE,
APPROVE, APPROVE,

View file

@ -42,7 +42,7 @@ import app.fedilab.android.ui.fragment.admin.FragmentAdminReport;
public class AdminActionActivity extends BaseActivity { public class AdminActionActivity extends BaseActivity {
public static Boolean local = true, remote = true, active = true, pending = true, disabled = true, silenced = true, suspended = true, staff = null, orderByMostRecent = true; public static Boolean local = true, remote = true, active = true, pending = true, disabled = true, silenced = true, suspended = true, staff = null, orderByMostRecent = true;
public static Boolean resolved = false, reportLocal = true, reportRemote = true; public static Boolean resolved = null, reportLocal = true, reportRemote = true;
private ActivityAdminActionsBinding binding; private ActivityAdminActionsBinding binding;
private boolean canGoBack; private boolean canGoBack;
private FragmentAdminReport fragmentAdminReport; private FragmentAdminReport fragmentAdminReport;
@ -227,7 +227,7 @@ public class AdminActionActivity extends BaseActivity {
if (checkedId == R.id.status_resolved) { if (checkedId == R.id.status_resolved) {
resolved = true; resolved = true;
} else if (checkedId == R.id.status_unresolved) { } else if (checkedId == R.id.status_unresolved) {
resolved = false; resolved = null;
} }
}); });
if (reportLocal != null && reportRemote == null) { if (reportLocal != null && reportRemote == null) {

View file

@ -25,13 +25,13 @@ public class AdminReport implements Serializable {
@SerializedName("id") @SerializedName("id")
public String id; public String id;
@SerializedName("account") @SerializedName("account")
public Account account; public AdminAccount account;
@SerializedName("action_taken") @SerializedName("action_taken")
public String action_taken; public Boolean action_taken;
@SerializedName("action_taken_by_account") @SerializedName("action_taken_by_account")
public String action_taken_by_account; public String action_taken_by_account;
@SerializedName("assigned_account") @SerializedName("assigned_account")
public Account assigned_account; public AdminAccount assigned_account;
@SerializedName("category") @SerializedName("category")
public String category; public String category;
@SerializedName("comment") @SerializedName("comment")
@ -39,7 +39,7 @@ public class AdminReport implements Serializable {
@SerializedName("created_at") @SerializedName("created_at")
public Date created_at; public Date created_at;
@SerializedName("target_account") @SerializedName("target_account")
public Account target_account; public AdminAccount target_account;
@SerializedName("statuses") @SerializedName("statuses")
public List<Status> statuses; public List<Status> statuses;
@SerializedName("rules") @SerializedName("rules")

View file

@ -0,0 +1,123 @@
package app.fedilab.android.ui.drawer;
/* Copyright 2022 Thomas Schneider
*
* This file is a part of Fedilab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
import java.util.List;
import app.fedilab.android.activities.AccountReportActivity;
import app.fedilab.android.client.entities.api.Account;
import app.fedilab.android.client.entities.api.AdminReport;
import app.fedilab.android.databinding.DrawerReportBinding;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
public class ReportAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<AdminReport> reports;
private Context context;
public ReportAdapter(List<AdminReport> reports) {
this.reports = reports;
}
@NotNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
context = parent.getContext();
DrawerReportBinding itemBinding = DrawerReportBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ReportViewHolder(itemBinding);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
ReportViewHolder holder = (ReportViewHolder) viewHolder;
AdminReport report = reports.get(position);
Account account = report.account.account;
Account target_account = report.target_account.account;
if (account.display_name == null || account.display_name.trim().equals("")) {
if (account.display_name != null && !account.display_name.trim().equals(""))
holder.binding.accountDnReporter.setText(account.display_name);
else
holder.binding.accountDnReporter.setText(account.username.replace("@", ""));
} else
holder.binding.accountDnReporter.setText(account.display_name, TextView.BufferType.SPANNABLE);
holder.binding.accountDn.setText(
report.account.account.getSpanDisplayName(context,
new WeakReference<>(holder.binding.accountDn)),
TextView.BufferType.SPANNABLE);
MastodonHelper.loadPPMastodon(holder.binding.accountPp, target_account);
MastodonHelper.loadPPMastodon(holder.binding.accountPpReporter, account);
if (target_account.acct != null) {
holder.binding.accountAc.setText(target_account.acct);
}
holder.binding.reportComment.setText(report.comment);
if (report.statuses != null) {
holder.binding.reportNumberStatus.setText(String.valueOf(report.statuses.size()));
} else {
holder.binding.reportNumberStatus.setText("0");
}
holder.binding.mainContainer.setOnClickListener(view -> {
Intent intent = new Intent(context, AccountReportActivity.class);
Bundle b = new Bundle();
b.putSerializable(Helper.ARG_REPORT, report);
intent.putExtras(b);
context.startActivity(intent);
});
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return reports.size();
}
public static class ReportViewHolder extends RecyclerView.ViewHolder {
DrawerReportBinding binding;
ReportViewHolder(DrawerReportBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
}
}

View file

@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -137,6 +138,9 @@ public class FragmentAdminAccount extends Fragment {
adminAccountAdapter = new AdminAccountAdapter(this.adminAccounts); adminAccountAdapter = new AdminAccountAdapter(this.adminAccounts);
flagLoading = adminAccounts.pagination.max_id == null; flagLoading = adminAccounts.pagination.max_id == null;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity()); LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity());
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(binding.recyclerView.getContext(),
mLayoutManager.getOrientation());
binding.recyclerView.addItemDecoration(dividerItemDecoration);
binding.recyclerView.setLayoutManager(mLayoutManager); binding.recyclerView.setLayoutManager(mLayoutManager);
binding.recyclerView.setAdapter(adminAccountAdapter); binding.recyclerView.setAdapter(adminAccountAdapter);
//Fetch the relationship //Fetch the relationship

View file

@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -38,7 +39,7 @@ import app.fedilab.android.client.entities.api.AdminReports;
import app.fedilab.android.databinding.FragmentPaginationBinding; import app.fedilab.android.databinding.FragmentPaginationBinding;
import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.ui.drawer.StatusAdapter; import app.fedilab.android.ui.drawer.ReportAdapter;
import app.fedilab.android.viewmodel.mastodon.AdminVM; import app.fedilab.android.viewmodel.mastodon.AdminVM;
@ -50,7 +51,7 @@ public class FragmentAdminReport extends Fragment {
private boolean flagLoading; private boolean flagLoading;
private List<AdminReport> adminReports; private List<AdminReport> adminReports;
private String max_id, min_id; private String max_id, min_id;
private StatusAdapter statusAdapter; private ReportAdapter reportAdapter;
private LinearLayoutManager mLayoutManager; private LinearLayoutManager mLayoutManager;
private String viewModelKey; private String viewModelKey;
@ -119,16 +120,15 @@ public class FragmentAdminReport extends Fragment {
} }
flagLoading = adminReports.pagination.max_id == null; flagLoading = adminReports.pagination.max_id == null;
binding.recyclerView.setVisibility(View.VISIBLE); binding.recyclerView.setVisibility(View.VISIBLE);
if (statusAdapter != null && this.adminReports != null) { if (reportAdapter != null && this.adminReports != null) {
int size = this.adminReports.size(); int size = this.adminReports.size();
this.adminReports.clear(); this.adminReports.clear();
this.adminReports = new ArrayList<>(); this.adminReports = new ArrayList<>();
statusAdapter.notifyItemRangeRemoved(0, size); reportAdapter.notifyItemRangeRemoved(0, size);
} }
if (this.adminReports == null) { if (this.adminReports == null) {
this.adminReports = new ArrayList<>(); this.adminReports = new ArrayList<>();
} }
this.adminReports.addAll(adminReports.adminReports); this.adminReports.addAll(adminReports.adminReports);
if (max_id == null || (adminReports.pagination.max_id != null && Helper.compareTo(adminReports.pagination.max_id, max_id) < 0)) { if (max_id == null || (adminReports.pagination.max_id != null && Helper.compareTo(adminReports.pagination.max_id, max_id) < 0)) {
@ -138,12 +138,14 @@ public class FragmentAdminReport extends Fragment {
min_id = adminReports.pagination.min_id; min_id = adminReports.pagination.min_id;
} }
// statusAdapter = new StatusAdapter(this.statuses, timelineType, minified); reportAdapter = new ReportAdapter(adminReports.adminReports);
mLayoutManager = new LinearLayoutManager(requireActivity()); mLayoutManager = new LinearLayoutManager(requireActivity());
binding.recyclerView.setLayoutManager(mLayoutManager); binding.recyclerView.setLayoutManager(mLayoutManager);
binding.recyclerView.setAdapter(statusAdapter); binding.recyclerView.setAdapter(reportAdapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(binding.recyclerView.getContext(),
mLayoutManager.getOrientation());
binding.recyclerView.addItemDecoration(dividerItemDecoration);
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
@ -189,7 +191,7 @@ public class FragmentAdminReport extends Fragment {
//There are some adminReports present in the timeline //There are some adminReports present in the timeline
int startId = adminReports.size(); int startId = adminReports.size();
adminReports.addAll(admReports.adminReports); adminReports.addAll(admReports.adminReports);
statusAdapter.notifyItemRangeInserted(startId, admReports.adminReports.size()); reportAdapter.notifyItemRangeInserted(startId, admReports.adminReports.size());
if (max_id == null || (admReports.pagination.max_id != null && Helper.compareTo(admReports.pagination.max_id, max_id) < 0)) { if (max_id == null || (admReports.pagination.max_id != null && Helper.compareTo(admReports.pagination.max_id, max_id) < 0)) {
max_id = admReports.pagination.max_id; max_id = admReports.pagination.max_id;
} }
@ -199,19 +201,6 @@ public class FragmentAdminReport extends Fragment {
} }
} }
@Override
public void onPause() {
super.onPause();
}
/**
* Refresh status in list
*/
public void refreshAllAdapters() {
if (statusAdapter != null && adminReports != null) {
statusAdapter.notifyItemRangeChanged(0, adminReports.size());
}
}
} }

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18z" />
</vector>

View file

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2022 Thomas Schneider
This file is a part of Fedilab
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical"
android:padding="10dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/account_pp"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/profile_picture" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/account_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/account_dn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="18sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/account_ac"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/account_pp_reporter"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:contentDescription="@string/profile_picture" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/account_dn_reporter"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textSize="18sp" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/report_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_baseline_mode_comment_24" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/report_number_status"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_weight="1" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>

View file

@ -16,7 +16,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:orientation="horizontal"> android:orientation="vertical">
<RadioButton <RadioButton
android:id="@+id/location_all" android:id="@+id/location_all"
@ -42,7 +42,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:text="@string/location" android:text="@string/state"
android:textSize="16sp" /> android:textSize="16sp" />
<RadioGroup <RadioGroup
@ -50,7 +50,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:orientation="horizontal"> android:orientation="vertical">
<RadioButton <RadioButton
android:id="@+id/moderation_all" android:id="@+id/moderation_all"

View file

@ -1596,4 +1596,5 @@
<string name="account_unsilenced">Account unsilenced</string> <string name="account_unsilenced">Account unsilenced</string>
<string name="account_silenced">Account silenced</string> <string name="account_silenced">Account silenced</string>
<string name="report">Report</string> <string name="report">Report</string>
<string name="state">State</string>
</resources> </resources>