Some layouts

This commit is contained in:
tom79 2019-06-19 14:58:57 +02:00
parent f8eacf704d
commit b636e54ec5
18 changed files with 1393 additions and 1 deletions

View File

@ -232,6 +232,11 @@
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
/>
<activity android:name="app.fedilab.android.activities.AdminActivity"
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
/>
<activity android:name="app.fedilab.android.activities.ReorderTimelinesActivity"
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="orientation|screenSize"

View File

@ -0,0 +1,169 @@
/* Copyright 2019 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>. */
package app.fedilab.android.activities;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import app.fedilab.android.R;
import app.fedilab.android.fragments.DisplayAdminAccountsFragment;
import app.fedilab.android.fragments.DisplayAdminReportsFragment;
import app.fedilab.android.helper.Helper;
/**
* Created by Thomas on 19/06/2019.
* Admin activity
*/
public class AdminActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
setTheme(R.style.AppAdminTheme);
if( getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActionBar actionBar = getSupportActionBar();
if( actionBar != null ) {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null;
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.simple_bar, null);
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
toolbar_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
toolbar_title.setText(String.format(getString(R.string.administration)+ " %s", Helper.getLiveInstance(getApplicationContext())));
}
setContentView(R.layout.activity_admin);
ViewPager admin_viewpager = findViewById(R.id.admin_viewpager);
TabLayout admin_tablayout = findViewById(R.id.admin_tablayout);
admin_tablayout.addTab(admin_tablayout.newTab().setText(getString(R.string.reports)));
admin_tablayout.addTab(admin_tablayout.newTab().setText(getString(R.string.accounts)));
PagerAdapter mPagerAdapter = new AdminPagerAdapter(getSupportFragmentManager());
admin_viewpager.setAdapter(mPagerAdapter);
admin_viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
TabLayout.Tab tab = admin_tablayout.getTabAt(position);
if( tab != null)
tab.select();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
admin_tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
admin_viewpager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
Fragment fragment = null;
if( admin_viewpager.getAdapter() != null)
fragment = (Fragment) admin_viewpager.getAdapter().instantiateItem(admin_viewpager, tab.getPosition());
switch (tab.getPosition()){
case 0:
if( fragment != null) {
DisplayAdminReportsFragment displayAdminReportsFragment = ((DisplayAdminReportsFragment) fragment);
displayAdminReportsFragment.scrollToTop();
}
break;
case 1:
if( fragment != null) {
DisplayAdminAccountsFragment displayAdminAccountsFragment = ((DisplayAdminAccountsFragment) fragment);
displayAdminAccountsFragment.scrollToTop();
}
break;
}
}
});
}
private class AdminPagerAdapter extends FragmentStatePagerAdapter {
AdminPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
switch (position){
case 0:
DisplayAdminReportsFragment displayAdminReportsFragment = new DisplayAdminReportsFragment();
return displayAdminReportsFragment;
case 1:
DisplayAdminAccountsFragment displayAdminAccountsFragment = new DisplayAdminAccountsFragment();
return displayAdminAccountsFragment;
}
return null;
}
@Override
public int getCount() {
return 2;
}
}
}

View File

@ -86,6 +86,7 @@ import app.fedilab.android.client.Entities.Status;
import app.fedilab.android.client.Entities.TagTimeline;
import app.fedilab.android.client.Entities.Version;
import app.fedilab.android.fragments.DisplayAccountsFragment;
import app.fedilab.android.fragments.DisplayAdminReportsFragment;
import app.fedilab.android.fragments.DisplayBookmarksFragment;
import app.fedilab.android.fragments.DisplayDraftsFragment;
import app.fedilab.android.fragments.DisplayFavoritesPeertubeFragment;
@ -284,6 +285,7 @@ public abstract class BaseMainActivity extends BaseActivity
viewPager = findViewById(R.id.viewpager);
new PostAdminActionAsyncTask(getApplicationContext(), API.adminAction.GET_ACCOUNTS, null, null, BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new PostAdminActionAsyncTask(getApplicationContext(), API.adminAction.GET_REPORTS, null, null, BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
display_timeline.setOnClickListener(new View.OnClickListener() {
@Override
@ -1512,6 +1514,10 @@ public abstract class BaseMainActivity extends BaseActivity
Intent intent = new Intent(getApplicationContext(), ReorderTimelinesActivity.class);
startActivity(intent);
return false;
}else if(id == R.id.nav_administration){
Intent intent = new Intent(getApplicationContext(), AdminActivity.class);
startActivity(intent);
return false;
} else if( id == R.id.nav_about) {
Intent intent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(intent);

View File

@ -114,12 +114,14 @@ public class LoginActivity extends BaseActivity {
private TextView instance_chosen;
private ImageView info_instance;
private final int PICK_IMPORT = 5557;
private boolean admin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
socialNetwork = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON;
admin = false;
if(b != null) {
autofilledInstance = b.getString("instance", null);
social = b.getString("social", null);
@ -136,6 +138,7 @@ public class LoginActivity extends BaseActivity {
break;
}
}
admin = b.getBoolean("admin", false);
}
if( getIntent() != null && getIntent().getData() != null && getIntent().getData().toString().contains("mastalab://backtomastalab?code=")){
@ -551,7 +554,11 @@ public class LoginActivity extends BaseActivity {
parameters.put(Helper.CLIENT_NAME, Helper.CLIENT_NAME_VALUE);
parameters.put(Helper.REDIRECT_URIS, client_id_for_webview?Helper.REDIRECT_CONTENT_WEB:Helper.REDIRECT_CONTENT);
if( socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
if( admin ) {
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_ADMIN);
}else{
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
}
}else {
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_PEERTUBE);
}

View File

@ -19,6 +19,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -234,6 +235,7 @@ public class API {
}
try {
String response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl(endpoint), 60, params, prefKeyOauthTokenT);
Log.v(Helper.TAG,response);
switch (action){
case GET_ACCOUNTS:
List<AccountAdmin> accountAdmins = parseAccountAdminResponse(new JSONArray(response));

View File

@ -0,0 +1,157 @@
package app.fedilab.android.drawers;
/* Copyright 2019 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.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.asynctasks.RetrieveAccountsAsyncTask;
import app.fedilab.android.client.Entities.Account;
import app.fedilab.android.client.Entities.AccountAdmin;
import app.fedilab.android.client.Entities.Report;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnRetrieveEmojiAccountInterface;
/**
* Created by Thomas on 19/06/2019.
* Adapter for account admins
*/
public class AccountsAdminListAdapter extends RecyclerView.Adapter implements OnRetrieveEmojiAccountInterface {
private List<AccountAdmin> accountAdmins;
private LayoutInflater layoutInflater;
private RetrieveAccountsAsyncTask.Type action;
private Context context;
private AccountsAdminListAdapter accountsAdminListAdapter;
private String targetedId;
public AccountsAdminListAdapter(Context context, List<AccountAdmin> accountAdmins){
this.context = context;
this.accountAdmins = accountAdmins;
layoutInflater = LayoutInflater.from(context);
this.accountsAdminListAdapter = this;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_account_admin, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final AccountsAdminListAdapter.ViewHolder holder = (AccountsAdminListAdapter.ViewHolder) viewHolder;
AccountAdmin accountAdmin = accountAdmins.get(position);
Account account = accountAdmin.getAccount();
account.makeAccountNameEmoji(context, AccountsAdminListAdapter.this, account);
if( account.getdisplayNameSpan() == null || account.getdisplayNameSpan().toString().trim().equals("")) {
if( account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
holder.account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
else
holder.account_dn.setText(account.getDisplay_name().replace("@",""));
}else
holder.account_dn.setText( account.getdisplayNameSpan(), TextView.BufferType.SPANNABLE);
if( account.getdisplayNameSpan() == null || account.getdisplayNameSpan().toString().trim().equals("")) {
if( account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
holder.account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
else
holder.account_dn.setText(account.getDisplay_name().replace("@",""));
}else
holder.account_dn.setText( account.getdisplayNameSpan(), TextView.BufferType.SPANNABLE);
holder.account_un.setText(String.format("@%s",account.getUsername()));
holder.account_ac.setText(account.getAcct());
if( account.getDisplay_name().equals(account.getAcct()))
holder.account_ac.setVisibility(View.GONE);
else
holder.account_ac.setVisibility(View.VISIBLE);
holder.report_action_taken.setText(accountAdmin.getIp());
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return accountAdmins.size();
}
private AccountAdmin getItemAt(int position){
if( accountAdmins.size() > position)
return accountAdmins.get(position);
else
return null;
}
@Override
public void onRetrieveEmojiAccount(Account account) {
notifyAccountChanged(account);
}
private void notifyAccountChanged(Account account){
for (int i = 0; i < accountsAdminListAdapter.getItemCount(); i++) {
//noinspection ConstantConditions
if (accountsAdminListAdapter.getItemAt(i) != null && accountsAdminListAdapter.getItemAt(i).getAccount().getId().equals(account.getId())) {
try {
accountsAdminListAdapter.notifyItemChanged(i);
} catch (Exception ignored) {
}
}
}
}
private class ViewHolder extends RecyclerView.ViewHolder{
ImageView account_pp;
TextView account_ac;
TextView account_dn;
TextView account_un;
TextView report_action_taken;
LinearLayout account_container;
ViewHolder(View itemView) {
super(itemView);
account_pp = itemView.findViewById(R.id.account_pp);
account_dn = itemView.findViewById(R.id.account_dn);
account_ac = itemView.findViewById(R.id.account_ac);
account_un = itemView.findViewById(R.id.account_un);
report_action_taken = itemView.findViewById(R.id.report_action_taken);
account_container = itemView.findViewById(R.id.account_container);
}
}
}

View File

@ -0,0 +1,160 @@
package app.fedilab.android.drawers;
/* Copyright 2019 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.os.Build;
import android.text.Html;
import android.text.util.Linkify;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.asynctasks.RetrieveAccountsAsyncTask;
import app.fedilab.android.client.Entities.Account;
import app.fedilab.android.client.Entities.Report;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnRetrieveEmojiAccountInterface;
/**
* Created by Thomas on 19/06/2019.
* Adapter for reports
*/
public class ReportsListAdapter extends RecyclerView.Adapter implements OnRetrieveEmojiAccountInterface {
private List<Report> reports;
private LayoutInflater layoutInflater;
private RetrieveAccountsAsyncTask.Type action;
private Context context;
private ReportsListAdapter reportsListAdapter;
private String targetedId;
public ReportsListAdapter(Context context, List<Report> reports){
this.context = context;
this.reports = reports;
layoutInflater = LayoutInflater.from(context);
this.reportsListAdapter = this;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_report, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final ReportsListAdapter.ViewHolder holder = (ReportsListAdapter.ViewHolder) viewHolder;
Report report = reports.get(position);
Account account = report.getStatuses().get(0).getAccount();
account.makeAccountNameEmoji(context, ReportsListAdapter.this, account);
if( account.getdisplayNameSpan() == null || account.getdisplayNameSpan().toString().trim().equals("")) {
if( account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
holder.account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
else
holder.account_dn.setText(account.getDisplay_name().replace("@",""));
}else
holder.account_dn.setText( account.getdisplayNameSpan(), TextView.BufferType.SPANNABLE);
if( account.getdisplayNameSpan() == null || account.getdisplayNameSpan().toString().trim().equals("")) {
if( account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
holder.account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
else
holder.account_dn.setText(account.getDisplay_name().replace("@",""));
}else
holder.account_dn.setText( account.getdisplayNameSpan(), TextView.BufferType.SPANNABLE);
holder.account_un.setText(String.format("@%s",account.getUsername()));
holder.account_ac.setText(account.getAcct());
if( account.getDisplay_name().equals(account.getAcct()))
holder.account_ac.setVisibility(View.GONE);
else
holder.account_ac.setVisibility(View.VISIBLE);
holder.report_action_taken.setText(report.getAction_taken());
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return reports.size();
}
private Report getItemAt(int position){
if( reports.size() > position)
return reports.get(position);
else
return null;
}
@Override
public void onRetrieveEmojiAccount(Account account) {
notifyAccountChanged(account);
}
private void notifyAccountChanged(Account account){
for (int i = 0; i < reportsListAdapter.getItemCount(); i++) {
//noinspection ConstantConditions
if (reportsListAdapter.getItemAt(i) != null && reportsListAdapter.getItemAt(i).getStatuses().get(0).getAccount().getId().equals(account.getId())) {
try {
reportsListAdapter.notifyItemChanged(i);
} catch (Exception ignored) {
}
}
}
}
private class ViewHolder extends RecyclerView.ViewHolder{
ImageView account_pp;
TextView account_ac;
TextView account_dn;
TextView account_un;
TextView report_action_taken;
LinearLayout account_container;
ViewHolder(View itemView) {
super(itemView);
account_pp = itemView.findViewById(R.id.account_pp);
account_dn = itemView.findViewById(R.id.account_dn);
account_ac = itemView.findViewById(R.id.account_ac);
account_un = itemView.findViewById(R.id.account_un);
report_action_taken = itemView.findViewById(R.id.report_action_taken);
account_container = itemView.findViewById(R.id.account_container);
}
}
}

View File

@ -0,0 +1,215 @@
package app.fedilab.android.fragments;
/* Copyright 2019 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.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.asynctasks.PostAdminActionAsyncTask;
import app.fedilab.android.asynctasks.RetrieveAccountsAsyncTask;
import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.AccountAdmin;
import app.fedilab.android.drawers.AccountsAdminListAdapter;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnAdminActionInterface;
import es.dmoral.toasty.Toasty;
/**
* Created by Thomas on 19/06/2019.
* Fragment to display content related to reports
*/
public class DisplayAdminAccountsFragment extends Fragment implements OnAdminActionInterface {
private boolean flag_loading;
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private AccountsAdminListAdapter accountsAdminListAdapter;
private String max_id;
private List<AccountAdmin> accountAdmins;
private RetrieveAccountsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private boolean swiped;
private RecyclerView lv_admin_accounts;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_admin_accounts, container, false);
context = getContext();
accountAdmins = new ArrayList<>();
max_id = null;
firstLoad = true;
flag_loading = true;
swiped = false;
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
lv_admin_accounts = rootView.findViewById(R.id.lv_admin_accounts);
lv_admin_accounts.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_accounts);
textviewNoAction = rootView.findViewById(R.id.no_action);
mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE);
accountsAdminListAdapter = new AccountsAdminListAdapter(context, this.accountAdmins);
lv_admin_accounts.setAdapter(accountsAdminListAdapter);
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(context);
lv_admin_accounts.setLayoutManager(mLayoutManager);
lv_admin_accounts.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (firstVisibleItem + visibleItemCount == totalItemCount) {
if (!flag_loading) {
flag_loading = true;
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminAccountsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
}
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
max_id = null;
accountAdmins = new ArrayList<>();
firstLoad = true;
flag_loading = true;
swiped = true;
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminAccountsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){
case Helper.THEME_LIGHT:
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,
R.color.mastodonC2,
R.color.mastodonC3);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.white));
break;
case Helper.THEME_DARK:
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4__,
R.color.mastodonC4,
R.color.mastodonC4);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.mastodonC1_));
break;
case Helper.THEME_BLACK:
swipeRefreshLayout.setColorSchemeResources(R.color.dark_icon,
R.color.mastodonC2,
R.color.mastodonC3);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.black_3));
break;
}
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminAccountsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return rootView;
}
@Override
public void onCreate(Bundle saveInstance)
{
super.onCreate(saveInstance);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
public void onDestroy() {
super.onDestroy();
if(asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
asyncTask.cancel(true);
}
public void scrollToTop(){
if( lv_admin_accounts != null)
lv_admin_accounts.setAdapter(accountsAdminListAdapter);
}
@Override
public void onAdminAction(APIResponse apiResponse) {
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
if( apiResponse.getError() != null){
Toasty.error(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
swipeRefreshLayout.setRefreshing(false);
swiped = false;
flag_loading = false;
return;
}
flag_loading = (apiResponse.getMax_id() == null );
List<AccountAdmin> accountAdmins = apiResponse.getAccountAdmins();
if( !swiped && firstLoad && (accountAdmins == null || accountAdmins.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
else
textviewNoAction.setVisibility(View.GONE);
max_id = apiResponse.getMax_id();
if( swiped ){
accountsAdminListAdapter = new AccountsAdminListAdapter(context, this.accountAdmins);
lv_admin_accounts.setAdapter(accountsAdminListAdapter);
swiped = false;
}
if( accountAdmins != null && accountAdmins.size() > 0) {
int currentPosition = this.accountAdmins.size();
this.accountAdmins.addAll(accountAdmins);
accountsAdminListAdapter.notifyItemRangeChanged(currentPosition,accountAdmins.size());
}
swipeRefreshLayout.setRefreshing(false);
firstLoad = false;
}
}

View File

@ -0,0 +1,245 @@
package app.fedilab.android.fragments;
/* Copyright 2019 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.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.activities.LoginActivity;
import app.fedilab.android.activities.PeertubeActivity;
import app.fedilab.android.asynctasks.PostActionAsyncTask;
import app.fedilab.android.asynctasks.PostAdminActionAsyncTask;
import app.fedilab.android.asynctasks.RetrieveAccountsAsyncTask;
import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.Report;
import app.fedilab.android.drawers.ReportsListAdapter;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnAdminActionInterface;
import es.dmoral.toasty.Toasty;
/**
* Created by Thomas on 19/06/2019.
* Fragment to display content related to reports
*/
public class DisplayAdminReportsFragment extends Fragment implements OnAdminActionInterface {
private boolean flag_loading;
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private ReportsListAdapter reportsListAdapter;
private String max_id;
private List<Report> reports;
private RetrieveAccountsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private boolean swiped;
private RecyclerView lv_reports;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_admin_reports, container, false);
context = getContext();
reports = new ArrayList<>();
max_id = null;
firstLoad = true;
flag_loading = true;
swiped = false;
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
lv_reports = rootView.findViewById(R.id.lv_reports);
lv_reports.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_accounts);
textviewNoAction = rootView.findViewById(R.id.no_action);
mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE);
reportsListAdapter = new ReportsListAdapter(context, this.reports);
lv_reports.setAdapter(reportsListAdapter);
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(context);
lv_reports.setLayoutManager(mLayoutManager);
lv_reports.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (firstVisibleItem + visibleItemCount == totalItemCount) {
if (!flag_loading) {
flag_loading = true;
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminReportsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
}
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
max_id = null;
reports = new ArrayList<>();
firstLoad = true;
flag_loading = true;
swiped = true;
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminReportsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){
case Helper.THEME_LIGHT:
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,
R.color.mastodonC2,
R.color.mastodonC3);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.white));
break;
case Helper.THEME_DARK:
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4__,
R.color.mastodonC4,
R.color.mastodonC4);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.mastodonC1_));
break;
case Helper.THEME_BLACK:
swipeRefreshLayout.setColorSchemeResources(R.color.dark_icon,
R.color.mastodonC2,
R.color.mastodonC3);
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(context, R.color.black_3));
break;
}
asyncTask = new PostAdminActionAsyncTask(context, API.adminAction.GET_REPORTS, null, null, DisplayAdminReportsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return rootView;
}
@Override
public void onCreate(Bundle saveInstance)
{
super.onCreate(saveInstance);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
public void onDestroy() {
super.onDestroy();
if(asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
asyncTask.cancel(true);
}
public void scrollToTop(){
if( lv_reports != null)
lv_reports.setAdapter(reportsListAdapter);
}
@Override
public void onAdminAction(APIResponse apiResponse) {
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
if( apiResponse.getError() != null){
Toasty.error(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
swipeRefreshLayout.setRefreshing(false);
swiped = false;
flag_loading = false;
//Admin right not granted through the API?
if( apiResponse.getError().getStatusCode() == 403){
AlertDialog.Builder builderInner;
builderInner = new AlertDialog.Builder(context, R.style.AppAdminTheme);
builderInner.setTitle(R.string.reconnect_account);
builderInner.setMessage(R.string.reconnect_account_message);
builderInner.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,int which) {
dialog.dismiss();
}
});
builderInner.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra("admin", true);
context.startActivity(intent);
}
});
builderInner.show();
}
return;
}
flag_loading = (apiResponse.getMax_id() == null );
List<Report> reports = apiResponse.getReports();
if( !swiped && firstLoad && (reports == null || reports.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
else
textviewNoAction.setVisibility(View.GONE);
max_id = apiResponse.getMax_id();
if( swiped ){
reportsListAdapter = new ReportsListAdapter(context, this.reports);
lv_reports.setAdapter(reportsListAdapter);
swiped = false;
}
if( reports != null && reports.size() > 0) {
int currentPosition = this.reports.size();
this.reports.addAll(reports);
reportsListAdapter.notifyItemRangeChanged(currentPosition,reports.size());
}
swipeRefreshLayout.setRefreshing(false);
firstLoad = false;
}
}

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#14161B"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/>
</vector>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
tools:context="app.fedilab.android.activities.AdminActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.google.android.material.tabs.TabLayout
android:id="@+id/admin_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabSelectedTextColor="?attr/colorAccent"
app:tabTextColor="?attr/textColor"
app:tabMode="fixed"
app:tabGravity="fill"
/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/admin_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:id="@+id/main_container"
android:orientation="horizontal">
<ImageView
android:layout_gravity="center_horizontal"
android:id="@+id/account_pp"
android:layout_width="60dp"
android:layout_height="60dp"
android:contentDescription="@string/profile_picture"/>
<LinearLayout
android:layout_marginStart="20dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="@+id/account_container"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/account_dn"
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/account_un"
android:maxLines="1"
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_height="wrap_content"
/>
</LinearLayout>
<TextView
android:layout_marginTop="10dp"
android:visibility="gone"
android:id="@+id/account_ac"
android:textSize="16sp"
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/report_action_taken"
android:textColor="?attr/colorAccent"
android:text="@string/request_sent"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:layout_gravity="center"
android:gravity="center"
/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:id="@+id/main_container"
android:orientation="horizontal">
<ImageView
android:layout_gravity="center_horizontal"
android:id="@+id/account_pp"
android:layout_width="60dp"
android:layout_height="60dp"
android:contentDescription="@string/profile_picture"/>
<LinearLayout
android:layout_marginStart="20dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="@+id/account_container"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/account_dn"
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/account_un"
android:maxLines="1"
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_height="wrap_content"
/>
</LinearLayout>
<TextView
android:layout_marginTop="10dp"
android:visibility="gone"
android:id="@+id/account_ac"
android:textSize="16sp"
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/report_action_taken"
android:textColor="?attr/colorAccent"
android:text="@string/request_sent"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:layout_gravity="center"
android:gravity="center"
/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="@dimen/fab_margin"
android:paddingRight="@dimen/fab_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Listview Accounts -->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:id="@+id/swipeContainer"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lv_admin_accounts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:divider="@null"
/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<RelativeLayout
android:id="@+id/no_action"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/no_action_text"
android:padding="10dp"
android:gravity="center"
android:textSize="25sp"
android:layout_gravity="center"
android:textStyle="italic|bold"
android:typeface="serif"
android:text="@string/no_accounts"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- Main Loader -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loader"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
<!-- Loader for next accounts -->
<RelativeLayout
android:id="@+id/loading_next_accounts"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|center_horizontal"
android:gravity="bottom|center_horizontal"
android:layout_height="20dp">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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>.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="@dimen/fab_margin"
android:paddingRight="@dimen/fab_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Listview Accounts -->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:id="@+id/swipeContainer"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lv_reports"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:divider="@null"
/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<RelativeLayout
android:id="@+id/no_action"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/no_action_text"
android:padding="10dp"
android:gravity="center"
android:textSize="25sp"
android:layout_gravity="center"
android:textStyle="italic|bold"
android:typeface="serif"
android:text="@string/no_reports"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- Main Loader -->
<RelativeLayout
android:id="@+id/loader"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
<!-- Loader for next accounts -->
<RelativeLayout
android:id="@+id/loading_next_accounts"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|center_horizontal"
android:gravity="bottom|center_horizontal"
android:layout_height="20dp">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true" />
</RelativeLayout>
</RelativeLayout>

View File

@ -58,6 +58,10 @@
android:id="@+id/nav_drag_timelines"
android:icon="@drawable/ic_drag_handle_menu"
android:title="@string/reorder_timelines" />
<item
android:id="@+id/nav_administration"
android:icon="@drawable/ic_security_admin"
android:title="@string/administration" />
</group>
</menu>
</item>

View File

@ -1028,6 +1028,11 @@
<b>Important</b>: If your instance required validation, you will receive an email once it is validated!
</string>
<string name="save_draft">Save the message in drafts?</string>
<string name="administration">Administration</string>
<string name="reports">Reports</string>
<string name="no_reports">No reports to display!</string>
<string name="reconnect_account">Reconnect the account</string>
<string name="reconnect_account_message">The application failed to access the admin features. You might need to reconnect the account for having the correct scope.</string>
<plurals name="number_of_vote">
<item quantity="one">%d vote</item>
<item quantity="other">%d votes</item>

View File

@ -392,4 +392,39 @@
<style name="Shape.Dark" parent="AppThemeDark">
<item name="android:background">@drawable/shape_border_bottom_settings_dark</item>
</style>
<!-- Light theme -->
<style name="AppAdminTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:textColor">@color/light_black</item>
<item name="colorPrimary">@color/mastodonC1</item>
<item name="colorPrimaryDark">@color/mastodonC1</item>
<item name="colorAccent">@color/mastodonC4</item>
<item name="cardBorder">@color/cardBorderLight</item>
<item name="textColor">@color/dark_text</item>
<item name="android:buttonStyle">@style/ButtonColor</item>
<item name="headerbg">@style/Header.Light</item>
<item name="android:windowBackground">@color/mastodonC1__</item>
<item name="shapeBorder">@style/Shape.Light</item>
<item name="imgbd">@style/Image.Border.Light</item>
<item name="borderless">@style/borderLessLightStyle</item>
<item name="borderlessColored">@style/borderlessColoredStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="popupOverlay">@style/AppTheme.PopupOverlay</item>
<item name="android:spinnerStyle">@style/SpinnerStyle</item>
<item name="android:spinnerItemStyle">@style/SpinnerItemStyle</item>
<item name="android:popupMenuStyle">@style/PopupMenu</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:actionModeStyle">@style/ActionMode</item>
<item name="android:dropDownListViewStyle">@style/DropDownListViewStyle</item>
<item name="actionBarTextColor">@color/dark_text</item>
<item name="color_in_account_header">@color/black</item>
<item name="colorBackgroundFloating">@color/mastodonC1__</item>
<item name="android:colorBackground">@color/mastodonC1__</item>
<item name="android:actionOverflowButtonStyle">@style/Widget.Admin.ActionButton.Overflow</item>
</style>
<style name="Widget.Admin.ActionButton.Overflow" parent="Base.Widget.AppCompat.ActionButton.Overflow">
<item name="android:contentDescription">@string/abc_action_menu_overflow_description</item>
</style>
</resources>