mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
[GSoC] Added Leaderboard Filters (#3902)
* Attempt to add filters * Basic Filter Working * Filter Improved * Filter Completed
This commit is contained in:
parent
baee56e392
commit
94952f1820
8 changed files with 222 additions and 23 deletions
|
|
@ -2,8 +2,6 @@ package fr.free.nrw.commons.profile.leaderboard;
|
||||||
|
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADED;
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADED;
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADING;
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADING;
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.PAGE_SIZE;
|
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.START_OFFSET;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
@ -20,10 +18,19 @@ public class DataSourceClass extends PageKeyedDataSource<Integer, LeaderboardLis
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
private MutableLiveData<String> progressLiveStatus;
|
private MutableLiveData<String> progressLiveStatus;
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
private String duration;
|
||||||
|
private String category;
|
||||||
|
private int limit;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
public DataSourceClass(OkHttpJsonApiClient okHttpJsonApiClient,SessionManager sessionManager) {
|
public DataSourceClass(OkHttpJsonApiClient okHttpJsonApiClient,SessionManager sessionManager,
|
||||||
|
String duration, String category, int limit, int offset) {
|
||||||
this.okHttpJsonApiClient = okHttpJsonApiClient;
|
this.okHttpJsonApiClient = okHttpJsonApiClient;
|
||||||
this.sessionManager = sessionManager;
|
this.sessionManager = sessionManager;
|
||||||
|
this.duration = duration;
|
||||||
|
this.category = category;
|
||||||
|
this.limit = limit;
|
||||||
|
this.offset = offset;
|
||||||
progressLiveStatus = new MutableLiveData<>();
|
progressLiveStatus = new MutableLiveData<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,7 +45,7 @@ public class DataSourceClass extends PageKeyedDataSource<Integer, LeaderboardLis
|
||||||
|
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
compositeDisposable.add(okHttpJsonApiClient
|
||||||
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
||||||
"all_time", "upload", String.valueOf(PAGE_SIZE), String.valueOf(START_OFFSET))
|
duration, category, String.valueOf(limit), String.valueOf(offset))
|
||||||
.doOnSubscribe(disposable -> {
|
.doOnSubscribe(disposable -> {
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
progressLiveStatus.postValue(LOADING);
|
progressLiveStatus.postValue(LOADING);
|
||||||
|
|
@ -68,7 +75,7 @@ public class DataSourceClass extends PageKeyedDataSource<Integer, LeaderboardLis
|
||||||
@NonNull LoadCallback<Integer, LeaderboardList> callback) {
|
@NonNull LoadCallback<Integer, LeaderboardList> callback) {
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
compositeDisposable.add(okHttpJsonApiClient
|
||||||
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
||||||
"all_time", "upload", String.valueOf(PAGE_SIZE), String.valueOf(params.key))
|
duration, category, String.valueOf(limit), String.valueOf(params.key))
|
||||||
.doOnSubscribe(disposable -> {
|
.doOnSubscribe(disposable -> {
|
||||||
compositeDisposable.add(disposable);
|
compositeDisposable.add(disposable);
|
||||||
progressLiveStatus.postValue(LOADING);
|
progressLiveStatus.postValue(LOADING);
|
||||||
|
|
@ -76,7 +83,7 @@ public class DataSourceClass extends PageKeyedDataSource<Integer, LeaderboardLis
|
||||||
response -> {
|
response -> {
|
||||||
if (response != null && response.getStatus() == 200) {
|
if (response != null && response.getStatus() == 200) {
|
||||||
progressLiveStatus.postValue(LOADED);
|
progressLiveStatus.postValue(LOADED);
|
||||||
callback.onResult(response.getLeaderboardList(), params.key + PAGE_SIZE);
|
callback.onResult(response.getLeaderboardList(), params.key + limit);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
t -> {
|
t -> {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,42 @@ public class DataSourceFactory extends DataSource.Factory<Integer, LeaderboardLi
|
||||||
private OkHttpJsonApiClient okHttpJsonApiClient;
|
private OkHttpJsonApiClient okHttpJsonApiClient;
|
||||||
private CompositeDisposable compositeDisposable;
|
private CompositeDisposable compositeDisposable;
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
private String duration;
|
||||||
|
private String category;
|
||||||
|
private int limit;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
public String getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(final String duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(final String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimit(final int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(final int offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
public DataSourceFactory(OkHttpJsonApiClient okHttpJsonApiClient, CompositeDisposable compositeDisposable,
|
public DataSourceFactory(OkHttpJsonApiClient okHttpJsonApiClient, CompositeDisposable compositeDisposable,
|
||||||
SessionManager sessionManager) {
|
SessionManager sessionManager) {
|
||||||
|
|
@ -27,7 +63,7 @@ public class DataSourceFactory extends DataSource.Factory<Integer, LeaderboardLi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataSource<Integer, LeaderboardList> create() {
|
public DataSource<Integer, LeaderboardList> create() {
|
||||||
DataSourceClass dataSourceClass = new DataSourceClass(okHttpJsonApiClient, sessionManager);
|
DataSourceClass dataSourceClass = new DataSourceClass(okHttpJsonApiClient, sessionManager, duration, category, limit, offset);
|
||||||
liveData.postValue(dataSourceClass);
|
liveData.postValue(dataSourceClass);
|
||||||
return dataSourceClass;
|
return dataSourceClass;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,19 @@ package fr.free.nrw.commons.profile.leaderboard;
|
||||||
|
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADED;
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADED;
|
||||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADING;
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.LOADING;
|
||||||
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.PAGE_SIZE;
|
||||||
|
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.START_OFFSET;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Spinner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.MergeAdapter;
|
import androidx.recyclerview.widget.MergeAdapter;
|
||||||
|
|
@ -35,6 +41,12 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
||||||
@BindView(R.id.progressBar)
|
@BindView(R.id.progressBar)
|
||||||
ProgressBar progressBar;
|
ProgressBar progressBar;
|
||||||
|
|
||||||
|
@BindView(R.id.category_spinner)
|
||||||
|
Spinner categorySpinner;
|
||||||
|
|
||||||
|
@BindView(R.id.duration_spinner)
|
||||||
|
Spinner durationSpinner;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SessionManager sessionManager;
|
SessionManager sessionManager;
|
||||||
|
|
||||||
|
|
@ -48,32 +60,91 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
||||||
|
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
String duration;
|
||||||
|
String category;
|
||||||
|
int limit = PAGE_SIZE;
|
||||||
|
int offset = START_OFFSET;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View rootView = inflater.inflate(R.layout.fragment_leaderboard, container, false);
|
View rootView = inflater.inflate(R.layout.fragment_leaderboard, container, false);
|
||||||
ButterKnife.bind(this, rootView);
|
ButterKnife.bind(this, rootView);
|
||||||
|
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
hideLayouts();
|
hideLayouts();
|
||||||
setLeaderboard();
|
setSpinners();
|
||||||
|
|
||||||
|
String[] durationValues = getContext().getResources().getStringArray(R.array.leaderboard_duration_values);
|
||||||
|
String[] categoryValues = getContext().getResources().getStringArray(R.array.leaderboard_category_values);
|
||||||
|
|
||||||
|
duration = durationValues[0];
|
||||||
|
category = categoryValues[0];
|
||||||
|
|
||||||
|
setLeaderboard(duration, category, limit, offset);
|
||||||
|
|
||||||
|
durationSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
|
||||||
|
duration = durationValues[durationSpinner.getSelectedItemPosition()];
|
||||||
|
refreshLeaderboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
categorySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
category = categoryValues[categorySpinner.getSelectedItemPosition()];
|
||||||
|
refreshLeaderboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshLeaderboard() {
|
||||||
|
if (viewModel != null) {
|
||||||
|
viewModel.refresh(duration, category, limit, offset);
|
||||||
|
setLeaderboard(duration, category, limit, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSpinners() {
|
||||||
|
ArrayAdapter<CharSequence> categoryAdapter = ArrayAdapter.createFromResource(getContext(),
|
||||||
|
R.array.leaderboard_categories, android.R.layout.simple_spinner_item);
|
||||||
|
categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
categorySpinner.setAdapter(categoryAdapter);
|
||||||
|
|
||||||
|
ArrayAdapter<CharSequence> durationAdapter = ArrayAdapter.createFromResource(getContext(),
|
||||||
|
R.array.leaderboard_durations, android.R.layout.simple_spinner_item);
|
||||||
|
durationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
durationSpinner.setAdapter(durationAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To call the API to get results
|
* To call the API to get results
|
||||||
* which then sets the views using setLeaderboardUser method
|
* which then sets the views using setLeaderboardUser method
|
||||||
*/
|
*/
|
||||||
private void setLeaderboard() {
|
private void setLeaderboard(String duration, String category, int limit, int offset) {
|
||||||
if (checkAccount()) {
|
if (checkAccount()) {
|
||||||
try {
|
try {
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
compositeDisposable.add(okHttpJsonApiClient
|
||||||
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
||||||
"all_time", "upload", null, null)
|
duration, category, null, null)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response -> {
|
response -> {
|
||||||
if (response != null && response.getStatus() == 200) {
|
if (response != null && response.getStatus() == 200) {
|
||||||
setViews(response);
|
setViews(response, duration, category, limit, offset);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
t -> {
|
t -> {
|
||||||
|
|
@ -92,22 +163,22 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
||||||
* Set the views
|
* Set the views
|
||||||
* @param response Leaderboard Response Object
|
* @param response Leaderboard Response Object
|
||||||
*/
|
*/
|
||||||
private void setViews(LeaderboardResponse response) {
|
private void setViews(LeaderboardResponse response, String duration, String category, int limit, int offset) {
|
||||||
viewModel = new ViewModelProvider(this, viewModelFactory).get(LeaderboardListViewModel.class);
|
viewModel = new ViewModelProvider(this, viewModelFactory).get(LeaderboardListViewModel.class);
|
||||||
|
viewModel.setParams(duration, category, limit, offset);
|
||||||
LeaderboardListAdapter leaderboardListAdapter = new LeaderboardListAdapter();
|
LeaderboardListAdapter leaderboardListAdapter = new LeaderboardListAdapter();
|
||||||
UserDetailAdapter userDetailAdapter= new UserDetailAdapter(response);
|
UserDetailAdapter userDetailAdapter= new UserDetailAdapter(response);
|
||||||
MergeAdapter mergeAdapter = new MergeAdapter(userDetailAdapter, leaderboardListAdapter);
|
MergeAdapter mergeAdapter = new MergeAdapter(userDetailAdapter, leaderboardListAdapter);
|
||||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
||||||
leaderboardListRecyclerView.setLayoutManager(linearLayoutManager);
|
leaderboardListRecyclerView.setLayoutManager(linearLayoutManager);
|
||||||
leaderboardListRecyclerView.setAdapter(mergeAdapter);
|
leaderboardListRecyclerView.setAdapter(mergeAdapter);
|
||||||
|
|
||||||
viewModel.getListLiveData().observe(getViewLifecycleOwner(), leaderboardListAdapter::submitList);
|
viewModel.getListLiveData().observe(getViewLifecycleOwner(), leaderboardListAdapter::submitList);
|
||||||
viewModel.getProgressLoadStatus().observe(getViewLifecycleOwner(), status -> {
|
viewModel.getProgressLoadStatus().observe(getViewLifecycleOwner(), status -> {
|
||||||
if (Objects.requireNonNull(status).equalsIgnoreCase(LOADING)) {
|
if (Objects.requireNonNull(status).equalsIgnoreCase(LOADING)) {
|
||||||
showProgressBar();
|
showProgressBar();
|
||||||
} else if (status.equalsIgnoreCase(LOADED)) {
|
} else if (status.equalsIgnoreCase(LOADED)) {
|
||||||
hideProgressBar();
|
hideProgressBar();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,6 +188,8 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
||||||
private void hideProgressBar() {
|
private void hideProgressBar() {
|
||||||
if (progressBar != null) {
|
if (progressBar != null) {
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
|
categorySpinner.setVisibility(View.VISIBLE);
|
||||||
|
durationSpinner.setVisibility(View.VISIBLE);
|
||||||
leaderboardListRecyclerView.setVisibility(View.VISIBLE);
|
leaderboardListRecyclerView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +207,8 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
||||||
* used to hide the layouts while fetching results from api
|
* used to hide the layouts while fetching results from api
|
||||||
*/
|
*/
|
||||||
private void hideLayouts(){
|
private void hideLayouts(){
|
||||||
|
categorySpinner.setVisibility(View.INVISIBLE);
|
||||||
|
durationSpinner.setVisibility(View.INVISIBLE);
|
||||||
leaderboardListRecyclerView.setVisibility(View.INVISIBLE);
|
leaderboardListRecyclerView.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ public class LeaderboardListViewModel extends ViewModel {
|
||||||
private DataSourceFactory dataSourceFactory;
|
private DataSourceFactory dataSourceFactory;
|
||||||
private LiveData<PagedList<LeaderboardList>> listLiveData;
|
private LiveData<PagedList<LeaderboardList>> listLiveData;
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
private LiveData<String> progressLoadStatus = new MutableLiveData<>();
|
private LiveData<String> progressLoadStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
public LeaderboardListViewModel(OkHttpJsonApiClient okHttpJsonApiClient, SessionManager sessionManager) {
|
public LeaderboardListViewModel(OkHttpJsonApiClient okHttpJsonApiClient, SessionManager
|
||||||
dataSourceFactory = new DataSourceFactory(okHttpJsonApiClient, compositeDisposable, sessionManager);
|
sessionManager) {
|
||||||
|
|
||||||
|
dataSourceFactory = new DataSourceFactory(okHttpJsonApiClient,
|
||||||
|
compositeDisposable, sessionManager);
|
||||||
initializePaging();
|
initializePaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,6 +44,21 @@ public class LeaderboardListViewModel extends ViewModel {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refresh(String duration, String category, int limit, int offset) {
|
||||||
|
dataSourceFactory.setDuration(duration);
|
||||||
|
dataSourceFactory.setCategory(category);
|
||||||
|
dataSourceFactory.setLimit(limit);
|
||||||
|
dataSourceFactory.setOffset(offset);
|
||||||
|
dataSourceFactory.getMutableLiveData().getValue().invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParams(String duration, String category, int limit, int offset) {
|
||||||
|
dataSourceFactory.setDuration(duration);
|
||||||
|
dataSourceFactory.setCategory(category);
|
||||||
|
dataSourceFactory.setLimit(limit);
|
||||||
|
dataSourceFactory.setOffset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<String> getProgressLoadStatus() {
|
public LiveData<String> getProgressLoadStatus() {
|
||||||
return progressLoadStatus;
|
return progressLoadStatus;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ public class ViewModelFactory implements ViewModelProvider.Factory {
|
||||||
private OkHttpJsonApiClient okHttpJsonApiClient;
|
private OkHttpJsonApiClient okHttpJsonApiClient;
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ViewModelFactory(OkHttpJsonApiClient okHttpJsonApiClient, SessionManager sessionManager) {
|
public ViewModelFactory(OkHttpJsonApiClient okHttpJsonApiClient, SessionManager sessionManager) {
|
||||||
this.okHttpJsonApiClient = okHttpJsonApiClient;
|
this.okHttpJsonApiClient = okHttpJsonApiClient;
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,44 @@
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/filters"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="1"
|
||||||
|
android:layout_margin="20dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:layout_marginStart="60dp"
|
||||||
|
android:id="@+id/duration_spinner"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:layout_marginEnd="60dp"
|
||||||
|
android:id="@+id/category_spinner"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/leaderboard_list"
|
android:id="@+id/leaderboard_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/filters" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,29 @@
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="leaderboard_categories">
|
||||||
|
<item>@string/leaderboard_upload</item>
|
||||||
|
<item>@string/leaderboard_used</item>
|
||||||
|
<item>@string/leaderboard_nearby</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="leaderboard_category_values">
|
||||||
|
<item>upload</item>
|
||||||
|
<item>used</item>
|
||||||
|
<item>nearby</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="leaderboard_durations">
|
||||||
|
<item>@string/leaderboard_weekly</item>
|
||||||
|
<item>@string/leaderboard_yearly</item>
|
||||||
|
<item>@string/leaderboard_all_time</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="leaderboard_duration_values">
|
||||||
|
<item>weekly</item>
|
||||||
|
<item>yearly</item>
|
||||||
|
<item>all_time</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -666,4 +666,10 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="avatar_set_successfully">Avatar Set Successfully</string>
|
<string name="avatar_set_successfully">Avatar Set Successfully</string>
|
||||||
<string name="avatar_set_unsuccessfully">Error setting new avatar, please try again</string>
|
<string name="avatar_set_unsuccessfully">Error setting new avatar, please try again</string>
|
||||||
<string name="menu_set_avatar">Set as avatar</string>
|
<string name="menu_set_avatar">Set as avatar</string>
|
||||||
|
<string name="leaderboard_yearly">Yearly</string>
|
||||||
|
<string name="leaderboard_weekly">Weekly</string>
|
||||||
|
<string name="leaderboard_all_time">All Time</string>
|
||||||
|
<string name="leaderboard_upload">Upload</string>
|
||||||
|
<string name="leaderboard_nearby">Nearby</string>
|
||||||
|
<string name="leaderboard_used">Used</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue