Instance Info page

This commit is contained in:
Balazs Toldi 2023-08-22 21:49:12 +02:00
parent 9d4657dea8
commit c7233e05c4
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
12 changed files with 619 additions and 9 deletions

View File

@ -108,6 +108,7 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
def lifecycleVersion = "2.5.1"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion"
@ -153,6 +154,7 @@ dependencies {
implementation "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
// Binding
// NOTE: Deprecated in favor of viewbinding
def butterknifeVersion = "10.2.3"

View File

@ -22,8 +22,7 @@
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".Infinity"
@ -35,6 +34,12 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:replace="android:label">
<activity
android:name=".activities.InstanceInfoActivity"
android:label="@string/instance_info"
android:configChanges="orientation|screenLayout|screenSize|layoutDirection"
android:parentActivityName=".activities.MainActivity"
android:theme="@style/AppTheme.Slidable" />
<activity
android:name=".activities.HistoryActivity"
android:exported="false"
@ -469,7 +474,6 @@
android:name=".activities.ViewUserDetailActivity"
android:parentActivityName=".activities.MainActivity"
android:theme="@style/AppTheme.Slidable" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"

View File

@ -2,6 +2,8 @@ package eu.toldi.infinityforlemmy;
import android.app.Application;
import org.jetbrains.annotations.NotNull;
import javax.inject.Singleton;
import dagger.BindsInstance;
@ -25,6 +27,7 @@ import eu.toldi.infinityforlemmy.activities.FullMarkdownActivity;
import eu.toldi.infinityforlemmy.activities.GiveAwardActivity;
import eu.toldi.infinityforlemmy.activities.HistoryActivity;
import eu.toldi.infinityforlemmy.activities.InboxActivity;
import eu.toldi.infinityforlemmy.activities.InstanceInfoActivity;
import eu.toldi.infinityforlemmy.activities.LinkResolverActivity;
import eu.toldi.infinityforlemmy.activities.LockScreenActivity;
import eu.toldi.infinityforlemmy.activities.LoginActivity;
@ -322,6 +325,8 @@ public interface AppComponent {
void inject(PrivateMessageFragment privateMessageFragment);
void inject(@NotNull InstanceInfoActivity instanceInfoActivity);
@Component.Factory
interface Factory {
AppComponent create(@BindsInstance Application application);

View File

@ -0,0 +1,225 @@
package eu.toldi.infinityforlemmy.activities;
import android.content.SharedPreferences;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.card.MaterialCardView;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.adapters.AdminRecyclerViewAdapter;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.databinding.ActivityInstanceInfoBinding;
import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.site.SiteStatistics;
import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.recycler.MarkwonAdapter;
public class InstanceInfoActivity extends BaseActivity {
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
@Named("no_oauth")
RetrofitHolder mRetorifitHolder;
ActivityInstanceInfoBinding mInstanceInfoActivityViewBinding;
private CoordinatorLayout coordinatorLayout;
private Toolbar toolbar;
private AppBarLayout appBarLayout;
private ConstraintLayout mLoadingConstraintLayout;
private MaterialCardView mStatisticsCardView;
private TextView mUsersTextView;
private TextView mCommunitiesTextView;
private TextView mPostsTextView;
private TextView mCommentsTextView;
private TextView mActiveUsersTextView;
private ImageView mUsersImageView;
private ImageView mCommunitiesImageView;
private ImageView mPostsImageView;
private ImageView mCommentsImageView;
private ImageView mActiveUsersImageView;
private MaterialCardView mDescriptionCardView;
private RecyclerView mContentMarkdownView;
private RecyclerView mAdminsRecyclerView;
private MaterialCardView mAdminsCardView;
private MarkwonAdapter mMarkwonAdapter;
private Markwon mPostDetailMarkwon;
private AdminRecyclerViewAdapter mAdminAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
mInstanceInfoActivityViewBinding = ActivityInstanceInfoBinding.inflate(getLayoutInflater());
View view = mInstanceInfoActivityViewBinding.getRoot();
setImmersiveModeNotApplicable();
setContentView(view);
setSupportActionBar(mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity);
setUpBindings();
applyCustomTheme();
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
Slidr.attach(this);
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
int markdownColor = customThemeWrapper.getPostContentColor();
int postSpoilerBackgroundColor = markdownColor | 0xFF000000;
int linkColor = customThemeWrapper.getLinkColor();
mPostDetailMarkwon = MarkdownUtils.createFullRedditMarkwon(this,
new AbstractMarkwonPlugin() {
}, markdownColor, postSpoilerBackgroundColor, null);
mMarkwonAdapter = MarkdownUtils.createTablesAdapter();
mContentMarkdownView.setAdapter(mMarkwonAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mContentMarkdownView.setLayoutManager(linearLayoutManager);
mAdminAdapter = new AdminRecyclerViewAdapter(InstanceInfoActivity.this, customThemeWrapper);
mAdminsRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(InstanceInfoActivity.this));
mAdminsRecyclerView.setAdapter(mAdminAdapter);
fetchInstanceInfo();
}
@Override
protected void onStart() {
super.onStart();
fetchInstanceInfo();
}
private void fetchInstanceInfo() {
FetchSiteInfo.fetchSiteInfo(mRetorifitHolder.getRetrofit(), null, new FetchSiteInfo.FetchSiteInfoListener() {
@Override
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) {
mLoadingConstraintLayout.setVisibility(View.GONE);
toolbar.setTitle(siteInfo.getName());
if (siteInfo.getSidebar() != null) {
mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, siteInfo.getSidebar());
Log.i("SiteInfo", "onFetchSiteInfoSuccess: " + siteInfo.getSidebar());
// noinspection NotifyDataSetChanged
mMarkwonAdapter.notifyDataSetChanged();
mDescriptionCardView.setVisibility(View.VISIBLE);
}
List<BasicUserInfo> admins = siteInfo.getAdmins();
if (admins != null && !admins.isEmpty()) {
mAdminsCardView.setVisibility(View.VISIBLE);
mAdminAdapter.setUsers(admins);
}
SiteStatistics siteStatistics = siteInfo.getSiteStatistics();
if (siteStatistics != null) {
mStatisticsCardView.setVisibility(View.VISIBLE);
mUsersTextView.setText(getString(R.string.user_number_detail, siteStatistics.getUsers()));
mCommunitiesTextView.setText(getString(R.string.community_number_detail, siteStatistics.getCommunities()));
mPostsTextView.setText(getString(R.string.post_count_detail, siteStatistics.getPosts()));
mCommentsTextView.setText(getString(R.string.comment_count_detail, siteStatistics.getComments()));
mActiveUsersTextView.setText(getString(R.string.active_users_number_detail, siteStatistics.getUsers_active()));
}
}
@Override
public void onFetchSiteInfoFailed() {
}
});
}
protected void setUpBindings() {
coordinatorLayout = mInstanceInfoActivityViewBinding.coordinatorLayoutInstanceInfoActivity;
toolbar = mInstanceInfoActivityViewBinding.toolbarInstanceInfoActivity;
appBarLayout = mInstanceInfoActivityViewBinding.appbarLayoutInstanceInfoActivity;
mStatisticsCardView = mInstanceInfoActivityViewBinding.statisticsCardInstanceInfoActivity;
mDescriptionCardView = mInstanceInfoActivityViewBinding.descriptionCardInstanceInfoActivity;
mContentMarkdownView = mInstanceInfoActivityViewBinding.markdownRecyclerViewInstanceInfoActivity;
mAdminsCardView = mInstanceInfoActivityViewBinding.moderatorsCardInstanceInfoActivity;
mLoadingConstraintLayout = mInstanceInfoActivityViewBinding.loadingLayoutInstanceInfoActivity;
mAdminsRecyclerView = mInstanceInfoActivityViewBinding.recyclerViewAdminsInstanceInfoActivity;
mUsersTextView = mInstanceInfoActivityViewBinding.registeredUserCountTextViewInstanceInfoActivity;
mCommunitiesTextView = mInstanceInfoActivityViewBinding.communityCountInstanceInfoActivity;
mPostsTextView = mInstanceInfoActivityViewBinding.postCountTextViewInstanceInfoActivity;
mCommentsTextView = mInstanceInfoActivityViewBinding.commentCountTextViewInstanceInfoActivity;
mActiveUsersTextView = mInstanceInfoActivityViewBinding.activeUserCountTextViewInstanceInfoActivity;
mUsersImageView = mInstanceInfoActivityViewBinding.registeredUserCountImageViewInstanceInfoActivity;
mCommunitiesImageView = mInstanceInfoActivityViewBinding.communitiesIconImageViewInstanceInfoActivity;
mPostsImageView = mInstanceInfoActivityViewBinding.postCountImageViewInstanceInfoActivity;
mCommentsImageView = mInstanceInfoActivityViewBinding.commentCountImageViewInstanceInfoActivity;
mActiveUsersImageView = mInstanceInfoActivityViewBinding.activeUserCountImageViewInstanceInfoActivity;
}
@Override
protected SharedPreferences getDefaultSharedPreferences() {
return mSharedPreferences;
}
@Override
protected CustomThemeWrapper getCustomThemeWrapper() {
return mCustomThemeWrapper;
}
@Override
protected void applyCustomTheme() {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar);
mUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mCommunitiesImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mPostsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mCommentsImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mActiveUsersImageView.setColorFilter(mCustomThemeWrapper.getPrimaryTextColor(), PorterDuff.Mode.SRC_IN);
mUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mCommunitiesTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mPostsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mCommentsTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
mActiveUsersTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return false;
}
}

View File

@ -882,9 +882,11 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
});
} else if (stringId == R.string.anonymous_account_instance) {
changeAnonymousAccountInstance();
} else if (stringId == R.string.blocks) {
intent = new Intent(MainActivity.this, BlockedThingListingActivity.class);
}
} else if (stringId == R.string.blocks) {
intent = new Intent(MainActivity.this, BlockedThingListingActivity.class);
} else if (stringId == R.string.instance_info) {
intent = new Intent(MainActivity.this, InstanceInfoActivity.class);
}
if (intent != null) {
startActivity(intent);
}

View File

@ -0,0 +1,22 @@
package eu.toldi.infinityforlemmy.adapters;
import eu.toldi.infinityforlemmy.activities.BaseActivity;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.user.BasicUserRecyclerViewAdapter;
public class AdminRecyclerViewAdapter extends BasicUserRecyclerViewAdapter {
CustomThemeWrapper mCustomThemeWrapper;
public AdminRecyclerViewAdapter(BaseActivity activity, CustomThemeWrapper customThemeWrapper) {
super(activity, customThemeWrapper);
mCustomThemeWrapper = customThemeWrapper;
}
@Override
protected int getUserNameTextColor() {
return mCustomThemeWrapper.getAdmin();
}
}

View File

@ -337,6 +337,11 @@ public class CustomThemeWrapper {
getDefaultColor("#577F63", "#D67AD2", "#25BE6A"));
}
public int getAdmin() {
return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.MODERATOR,
getDefaultColor("#a5222f", "#c94f6d", "#EE5396"));
}
public int getCurrentUser() {
return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CURRENT_USER,
getDefaultColor("#488D93", "#7AD5D6", "#2DC7C4"));

View File

@ -1,8 +1,15 @@
package eu.toldi.infinityforlemmy.site;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
public class SiteInfo {
private int id;
@ -13,7 +20,11 @@ public class SiteInfo {
private boolean enable_nsfw;
private boolean community_creation_admin_only;
public SiteInfo(int id, String name, String sidebar, String description, boolean enable_downvotes, boolean enable_nsfw, boolean community_creation_admin_only) {
private List<BasicUserInfo> admins;
SiteStatistics siteStatistics;
public SiteInfo(int id, String name, String sidebar, String description, boolean enable_downvotes, boolean enable_nsfw, boolean community_creation_admin_only, List<BasicUserInfo> admins, SiteStatistics siteStatistics) {
this.id = id;
this.name = name;
this.sidebar = sidebar;
@ -21,6 +32,8 @@ public class SiteInfo {
this.enable_downvotes = enable_downvotes;
this.enable_nsfw = enable_nsfw;
this.community_creation_admin_only = community_creation_admin_only;
this.admins = admins;
this.siteStatistics = siteStatistics;
}
public int getId() {
@ -51,6 +64,14 @@ public class SiteInfo {
return community_creation_admin_only;
}
public List<BasicUserInfo> getAdmins() {
return admins;
}
public SiteStatistics getSiteStatistics() {
return siteStatistics;
}
public static SiteInfo parseSiteInfo(String siteInfoJson) {
try {
JSONObject siteInfo = new JSONObject(siteInfoJson);
@ -72,9 +93,20 @@ public class SiteInfo {
boolean enable_nsfw = localSite.getBoolean("enable_nsfw");
boolean community_creation_admin_only = localSite.getBoolean("community_creation_admin_only");
SiteInfo si = new SiteInfo(id, name, sidebar, description, enable_downvotes, enable_nsfw, community_creation_admin_only);
JSONObject counts = siteView.getJSONObject("counts");
List<BasicUserInfo> admins = new ArrayList<>();
if (siteInfo.has("admins")) {
JSONArray adminsJson = siteInfo.getJSONArray("admins");
for (int i = 0; i < adminsJson.length(); i++) {
JSONObject adminJson = adminsJson.getJSONObject(i).getJSONObject("person");
admins.add(new BasicUserInfo(adminJson.getInt("id"), adminJson.getString("name"),
LemmyUtils.actorID2FullName(adminJson.getString("actor_id")), adminJson.optString("avatar ", ""),
adminJson.optString("display_name", adminJson.getString("name")))
);
}
}
return si;
return new SiteInfo(id, name, sidebar, description, enable_downvotes, enable_nsfw, community_creation_admin_only, admins, SiteStatistics.parseSiteStatistics(counts));
} catch (JSONException e) {
e.printStackTrace();
return null;

View File

@ -0,0 +1,55 @@
package eu.toldi.infinityforlemmy.site;
import org.json.JSONException;
import org.json.JSONObject;
public class SiteStatistics {
private final int users;
private final int posts;
private final int comments;
private final int communities;
private final int users_active;
public SiteStatistics(int users, int posts, int comments, int communities, int users_active) {
this.users = users;
this.posts = posts;
this.comments = comments;
this.communities = communities;
this.users_active = users_active;
}
public int getUsers() {
return users;
}
public int getPosts() {
return posts;
}
public int getComments() {
return comments;
}
public int getCommunities() {
return communities;
}
public int getUsers_active() {
return users_active;
}
public static SiteStatistics parseSiteStatistics(JSONObject countsJson) {
try {
int users = countsJson.getInt("users");
int posts = countsJson.getInt("posts");
int comments = countsJson.getInt("comments");
int communities = countsJson.getInt("communities");
int users_active = countsJson.getInt("users_active_month");
return new SiteStatistics(users, posts, comments, communities, users_active);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,10 @@
<vector android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M12,12.75c1.63,0 3.07,0.39 4.24,0.9c1.08,0.48 1.76,1.56 1.76,2.73L18,18H6l0,-1.61c0,-1.18 0.68,-2.26 1.76,-2.73C8.93,13.14 10.37,12.75 12,12.75zM4,13c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2C2,12.1 2.9,13 4,13zM5.13,14.1C4.76,14.04 4.39,14 4,14c-0.99,0 -1.93,0.21 -2.78,0.58C0.48,14.9 0,15.62 0,16.43V18l4.5,0v-1.61C4.5,15.56 4.73,14.78 5.13,14.1zM20,13c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2C18,12.1 18.9,13 20,13zM24,16.43c0,-0.81 -0.48,-1.53 -1.22,-1.85C21.93,14.21 20.99,14 20,14c-0.39,0 -0.76,0.04 -1.13,0.1c0.4,0.68 0.63,1.46 0.63,2.29V18l4.5,0V16.43zM12,6c1.66,0 3,1.34 3,3c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3C9,7.34 10.34,6 12,6z" />
</vector>

View File

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coordinator_layout_instance_info_activity"
tools:application="eu.toldi.infinityforlemmy.activities.InstanceInfoActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_layout_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:navigationIcon="?attr/homeAsUpIndicator" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading_layout_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/moderators_card_instance_info_activity"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/moderators_text_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/admins"
android:textSize="16sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_admins_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:visibility="visible" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/statistics_card_instance_info_activity"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/community_statistics_block_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="visible">
<ImageView
android:id="@+id/registered_user_count_image_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_person_24" />
<TextView
android:id="@+id/registered_user_count_text_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="10dp"
android:text="@string/user_number_detail"
app:layout_constraintStart_toEndOf="@+id/registered_user_count_image_view_instance_info_activity"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<ImageView
android:id="@+id/active_user_count_image_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="@+id/guideline7"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_bolt_24" />
<TextView
android:id="@+id/active_user_count_text_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="10dp"
android:text="@string/active_users_number_detail"
app:layout_constraintStart_toEndOf="@+id/active_user_count_image_view_instance_info_activity"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/post_count_image_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/registered_user_count_image_view_instance_info_activity"
app:srcCompat="@drawable/ic_post_add_24" />
<TextView
android:id="@+id/post_count_text_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="18dp"
android:text="@string/post_count_detail"
app:layout_constraintStart_toEndOf="@+id/post_count_image_view_instance_info_activity"
app:layout_constraintTop_toBottomOf="@+id/registered_user_count_image_view_instance_info_activity" />
<ImageView
android:id="@+id/comment_count_image_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="@+id/guideline7"
app:layout_constraintTop_toBottomOf="@+id/active_user_count_image_view_instance_info_activity"
app:srcCompat="@drawable/ic_comment_black_24" />
<TextView
android:id="@+id/comment_count_text_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="18dp"
android:text="@string/comment_count_detail"
app:layout_constraintStart_toEndOf="@+id/comment_count_image_view_instance_info_activity"
app:layout_constraintTop_toBottomOf="@+id/active_user_count_image_view_instance_info_activity" />
<ImageView
android:id="@+id/communities_icon_image_view_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/post_count_image_view_instance_info_activity"
app:srcCompat="@drawable/ic_groups_24" />
<TextView
android:id="@+id/community_count_instance_info_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="18dp"
android:text="@string/community_number_detail"
app:layout_constraintStart_toEndOf="@+id/communities_icon_image_view_instance_info_activity"
app:layout_constraintTop_toBottomOf="@+id/post_count_image_view_instance_info_activity" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/description_card_instance_info_activity"
style="?attr/materialCardViewElevatedStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/markdown_recycler_view_instance_info_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:paddingBottom="144dp"
android:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -150,6 +150,8 @@
<string name="active_users_number_detail">%1$,d Active Users</string>
<string name="post_count_detail">%1$,d Posts</string>
<string name="comment_count_detail">%1$,d Comments</string>
<string name="user_number_detail">%1$,d Users</string>
<string name="community_number_detail">%1$,d Communities</string>
<string name="online_subscribers_number_detail">Online: %1$,d</string>
<string name="cannot_fetch_community_info">Cannot fetch community info</string>
<string name="cannot_fetch_user_info">Cannot fetch user info</string>
@ -1379,4 +1381,5 @@
<string name="settings_show_statistics">Show Statistics</string>
<string name="settings_show_post_and_comment_score">Show post and comment scores</string>
<string name="moderators">Moderators</string>
<string name="admins">Admins</string>
</resources>