mirror of
https://framagit.org/tom79/fedilab-tube
synced 2025-04-14 02:21:59 +02:00
comment #5 - searches
This commit is contained in:
parent
fb83a1927d
commit
fd7632f001
@ -22,7 +22,6 @@ import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.EditText;
|
||||
@ -151,7 +150,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
overviewFragment = new DisplayOverviewFragment();
|
||||
|
||||
Log.v(Helper.TAG,"active: " + active);
|
||||
if( active == null) {
|
||||
active = overviewFragment;
|
||||
}
|
||||
|
@ -16,29 +16,286 @@ package app.fedilab.fedilabtube;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import app.fedilab.fedilabtube.fragment.DisplayVideosFragment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import app.fedilab.fedilabtube.viewmodel.SepiaSearchVM;
|
||||
import mabbas007.tagsedittext.TagsEditText;
|
||||
|
||||
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
|
||||
|
||||
|
||||
public class SepiaSearchActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private SepiaSearch sepiaSearchVideo;
|
||||
private SepiaSearch sepiaSearchChannel;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_sepia_search);
|
||||
|
||||
sepiaSearchVideo = new SepiaSearch();
|
||||
sepiaSearchChannel = new SepiaSearch();
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
|
||||
Button filter = findViewById(R.id.filter);
|
||||
ConstraintLayout filter_elements = findViewById(R.id.filter_elements);
|
||||
filter.setOnClickListener(view -> {
|
||||
if( filter_elements.getVisibility() == View.VISIBLE) {
|
||||
filter_elements.setVisibility(View.GONE);
|
||||
}else{
|
||||
filter_elements.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
RadioGroup sepia_element_nsfw = findViewById(R.id.sepia_element_nsfw);
|
||||
sepia_element_nsfw.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
if (checkedId == R.id.sepia_element_nsfw_no) {
|
||||
sepiaSearchVideo.setNsfw(false);
|
||||
} else {
|
||||
sepiaSearchVideo.setNsfw(true);
|
||||
}
|
||||
});
|
||||
|
||||
RadioGroup radio_date = findViewById(R.id.radio_date);
|
||||
radio_date.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
switch(checkedId){
|
||||
case R.id.sepia_element_published_date_today:
|
||||
Calendar cal = GregorianCalendar.getInstance();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
sepiaSearchVideo.setStartDate(cal.getTime());
|
||||
break;
|
||||
case R.id.sepia_element_published_date_last_7_days:
|
||||
cal = GregorianCalendar.getInstance();
|
||||
cal.setTime(new Date());
|
||||
cal.add(Calendar.DAY_OF_YEAR, -7);
|
||||
sepiaSearchVideo.setStartDate(cal.getTime());
|
||||
break;
|
||||
case R.id.sepia_element_published_date_last_30_days:
|
||||
cal = GregorianCalendar.getInstance();
|
||||
cal.setTime(new Date());
|
||||
cal.add(Calendar.DAY_OF_YEAR, -30);
|
||||
sepiaSearchVideo.setStartDate(cal.getTime());
|
||||
break;
|
||||
case R.id.sepia_element_published_date_last_365_days:
|
||||
cal = GregorianCalendar.getInstance();
|
||||
cal.setTime(new Date());
|
||||
cal.add(Calendar.DAY_OF_YEAR, -365);
|
||||
sepiaSearchVideo.setStartDate(cal.getTime());
|
||||
break;
|
||||
default:
|
||||
sepiaSearchVideo.setStartDate(null);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
RadioGroup duration = findViewById(R.id.duration);
|
||||
duration.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
switch(checkedId){
|
||||
case R.id.sepia_element_duration_short:
|
||||
sepiaSearchVideo.setDurationMin(0);
|
||||
sepiaSearchVideo.setDurationMax(240);
|
||||
break;
|
||||
case R.id.sepia_element_duration_medium:
|
||||
sepiaSearchVideo.setDurationMin(240);
|
||||
sepiaSearchVideo.setDurationMax(600);
|
||||
break;
|
||||
case R.id.sepia_element_duration_long:
|
||||
sepiaSearchVideo.setDurationMin(600);
|
||||
sepiaSearchVideo.setDurationMax(999999999);
|
||||
break;
|
||||
default:
|
||||
sepiaSearchVideo.setDurationMin(0);
|
||||
sepiaSearchVideo.setDurationMax(999999999);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
Spinner sort_by = findViewById(R.id.sort_by);
|
||||
ArrayAdapter<String> adapterSortBy = new ArrayAdapter<>(SepiaSearchActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, getResources().getStringArray(R.array.sort_by_array));
|
||||
sort_by.setAdapter(adapterSortBy);
|
||||
sort_by.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
String orderby, channelOrderBy;
|
||||
switch (position){
|
||||
case 1:
|
||||
orderby = "-publishedAt";
|
||||
channelOrderBy = "-createdAt";
|
||||
break;
|
||||
case 2:
|
||||
orderby = "publishedAt";
|
||||
channelOrderBy = "createdAt";
|
||||
break;
|
||||
default:
|
||||
orderby = "-match";
|
||||
channelOrderBy = null;
|
||||
}
|
||||
sepiaSearchVideo.setSort(orderby);
|
||||
sepiaSearchChannel.setSort(channelOrderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Spinner sepia_element_category = findViewById(R.id.sepia_element_category);
|
||||
Spinner sepia_element_license = findViewById(R.id.sepia_element_license);
|
||||
Spinner sepia_element_language = findViewById(R.id.sepia_element_language);
|
||||
|
||||
TagsEditText sepia_element_all_of_tags = findViewById(R.id.sepia_element_all_of_tags);
|
||||
TagsEditText sepia_element_one_of_tags = findViewById(R.id.sepia_element_one_of_tags);
|
||||
|
||||
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
LinkedHashMap<Integer, String> licences = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
LinkedHashMap<String, String> translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
|
||||
|
||||
//Populate catgories
|
||||
String[] categoriesA = new String[categories.size()+1];
|
||||
categoriesA[0] = getString(R.string.display_all_categories);
|
||||
Iterator<Map.Entry<Integer, String>> it = categories.entrySet().iterator();
|
||||
int i = 1;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Integer, String> pair = it.next();
|
||||
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
|
||||
categoriesA[i] = pair.getValue();
|
||||
else
|
||||
categoriesA[i] = translations.get(pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterCatgories = new ArrayAdapter<>(SepiaSearchActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, categoriesA);
|
||||
sepia_element_category.setAdapter(adapterCatgories);
|
||||
|
||||
|
||||
//Populate licenses
|
||||
String[] licensesA = new String[licences.size()+1];
|
||||
licensesA[0] = getString(R.string.display_all_licenses);
|
||||
it = licences.entrySet().iterator();
|
||||
i = 1;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Integer, String> pair = it.next();
|
||||
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
|
||||
licensesA[i] = pair.getValue();
|
||||
else
|
||||
licensesA[i] = translations.get(pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterLicenses = new ArrayAdapter<>(SepiaSearchActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, licensesA);
|
||||
sepia_element_license.setAdapter(adapterLicenses);
|
||||
|
||||
//Populate languages
|
||||
String[] languagesA = new String[languages.size()+1];
|
||||
languagesA[0] = getString(R.string.display_all_languages);
|
||||
Iterator<Map.Entry<String, String>> itl = languages.entrySet().iterator();
|
||||
i = 1;
|
||||
while (itl.hasNext()) {
|
||||
Map.Entry<String, String> pair = itl.next();
|
||||
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
|
||||
languagesA[i] = pair.getValue();
|
||||
else
|
||||
languagesA[i] = translations.get(pair.getValue());
|
||||
itl.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterLanguages = new ArrayAdapter<>(SepiaSearchActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, languagesA);
|
||||
sepia_element_language.setAdapter(adapterLanguages);
|
||||
|
||||
|
||||
sepia_element_license.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
updateLicensePosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
//Manage categories
|
||||
sepia_element_category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
updateCategoryPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Manage languages
|
||||
sepia_element_language.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
updateLanguagesPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
Button apply_filter = findViewById(R.id.apply_filter);
|
||||
apply_filter.setOnClickListener(v->{
|
||||
if( sepia_element_one_of_tags.getTags().size() > 0 ) {
|
||||
sepiaSearchVideo.setTagsOneOf(sepia_element_one_of_tags.getTags());
|
||||
}else{
|
||||
sepiaSearchVideo.setTagsOneOf(null);
|
||||
}
|
||||
if( sepia_element_all_of_tags.getTags().size() > 0 ) {
|
||||
sepiaSearchVideo.setTagsAllOf(sepia_element_all_of_tags.getTags());
|
||||
}else{
|
||||
sepiaSearchVideo.setTagsAllOf(null);
|
||||
}
|
||||
SepiaSearchVM sepiaSearchVM = new ViewModelProvider(SepiaSearchActivity.this).get(SepiaSearchVM.class);
|
||||
sepiaSearchVM.sepiaSearch(sepiaSearchVideo).observe(SepiaSearchActivity.this, this::manageVideos);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -51,4 +308,65 @@ public class SepiaSearchActivity extends AppCompatActivity {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void manageVideos(VideoData videoData) {
|
||||
|
||||
}
|
||||
|
||||
private void updateLanguagesPosition(int position) {
|
||||
LinkedHashMap<String, String> languagesCheck = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
Iterator<Map.Entry<String, String>> it = languagesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, String> pair = it.next();
|
||||
if (i == position && position > 0) {
|
||||
List<String> languages = new ArrayList<>();
|
||||
languages.add(pair.getKey());
|
||||
sepiaSearchVideo.setBoostLanguages(languages);
|
||||
break;
|
||||
}else {
|
||||
sepiaSearchVideo.setBoostLanguages(null);
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCategoryPosition(int position) {
|
||||
LinkedHashMap<Integer, String> categoriesCheck = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
Iterator<Map.Entry<Integer, String>> it = categoriesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Integer, String> pair = it.next();
|
||||
if (i == position && position > 0 ) {
|
||||
List<Integer> categories = new ArrayList<>();
|
||||
categories.add(pair.getKey());
|
||||
sepiaSearchVideo.setCategoryOneOf(categories);
|
||||
break;
|
||||
}else {
|
||||
sepiaSearchVideo.setCategoryOneOf(null);
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLicensePosition(int position) {
|
||||
LinkedHashMap<Integer, String> licensesCheck = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
Iterator<Map.Entry<Integer, String>> it = licensesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Integer, String> pair = it.next();
|
||||
if (i == position && position > 0) {
|
||||
List<Integer> licenses = new ArrayList<>();
|
||||
licenses.add(pair.getKey());
|
||||
sepiaSearchVideo.setLicenceOneOf(licenses);
|
||||
break;
|
||||
}else {
|
||||
sepiaSearchVideo.setLicenceOneOf(null);
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,26 +17,25 @@ package app.fedilab.fedilabtube.client;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import app.fedilab.fedilabtube.R;
|
||||
import java.io.IOException;
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
class RetrofitSepiaSearchAPI {
|
||||
public class RetrofitSepiaSearchAPI {
|
||||
|
||||
|
||||
private String finalUrl;
|
||||
private Context _context;
|
||||
private Set<String> selection;
|
||||
private String count;
|
||||
|
||||
|
||||
public RetrofitSepiaSearchAPI(Context context) {
|
||||
_context = context;
|
||||
finalUrl = "https://search.joinpeertube.org/api/v1/";
|
||||
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
count = String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE));
|
||||
}
|
||||
|
||||
@ -45,11 +44,38 @@ class RetrofitSepiaSearchAPI {
|
||||
.baseUrl(finalUrl)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
selection = sharedpreferences.getStringSet(_context.getString(R.string.set_video_language_choice), null);
|
||||
return retrofit.create(SepiaSearchService.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return videos for a sepia search
|
||||
* @param sepiaSearch SepiaSearch
|
||||
* @return VideoData
|
||||
*/
|
||||
public VideoData getVideos(SepiaSearch sepiaSearch) {
|
||||
SepiaSearchService sepiaSearchService = init();
|
||||
Call<VideoData> videoDataCall = sepiaSearchService.getVideos(
|
||||
sepiaSearch.getStart(),
|
||||
count,
|
||||
sepiaSearch.getSearch(),
|
||||
sepiaSearch.getDurationMax(),
|
||||
sepiaSearch.getStartDate(),
|
||||
sepiaSearch.getBoostLanguages(),
|
||||
sepiaSearch.getCategoryOneOf(),
|
||||
sepiaSearch.getLicenceOneOf(),
|
||||
sepiaSearch.getTagsOneOf(),
|
||||
sepiaSearch.getTagsAllOf(),
|
||||
sepiaSearch.isNsfw(),
|
||||
sepiaSearch.getSort());
|
||||
try {
|
||||
Response<VideoData> response = videoDataCall.execute();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
return response.body();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ interface SepiaSearchService {
|
||||
@Query("durationMax") int durationMax,
|
||||
@Query("startDate") Date startDate,
|
||||
@Query("boostLanguages") List<String> languageOneOf,
|
||||
@Query("categoryOneOf") List<String> categoryOneOf,
|
||||
@Query("licenceOneOf") List<String> licenceOneOf,
|
||||
@Query("categoryOneOf") List<Integer> categoryOneOf,
|
||||
@Query("licenceOneOf") List<Integer> licenceOneOf,
|
||||
@Query("tagsOneOf") List<String> tagsOneOf,
|
||||
@Query("tagsAllOf") List<String> tagsAllOf,
|
||||
@Query("nsfw") boolean nsfw,
|
||||
|
@ -19,11 +19,12 @@ import android.os.Parcelable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
class SepiaSearch implements Parcelable {
|
||||
public class SepiaSearch implements Parcelable {
|
||||
|
||||
@SerializedName("start")
|
||||
private String start;
|
||||
@ -33,14 +34,16 @@ class SepiaSearch implements Parcelable {
|
||||
private String search;
|
||||
@SerializedName("durationMax")
|
||||
private int durationMax;
|
||||
@SerializedName("durationMin")
|
||||
private int durationMin;
|
||||
@SerializedName("startDate")
|
||||
private Date startDate;
|
||||
@SerializedName("boostLanguages")
|
||||
private List<String> boostLanguages;
|
||||
@SerializedName("categoryOneOf")
|
||||
private List<String> categoryOneOf;
|
||||
private List<Integer> categoryOneOf;
|
||||
@SerializedName("licenceOneOf")
|
||||
private List<String> licenceOneOf;
|
||||
private List<Integer> licenceOneOf;
|
||||
@SerializedName("tagsOneOf")
|
||||
private List<String> tagsOneOf;
|
||||
@SerializedName("tagsAllOf")
|
||||
@ -84,6 +87,14 @@ class SepiaSearch implements Parcelable {
|
||||
this.durationMax = durationMax;
|
||||
}
|
||||
|
||||
public int getDurationMin() {
|
||||
return durationMin;
|
||||
}
|
||||
|
||||
public void setDurationMin(int durationMin) {
|
||||
this.durationMin = durationMin;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
@ -100,19 +111,19 @@ class SepiaSearch implements Parcelable {
|
||||
this.boostLanguages = boostLanguages;
|
||||
}
|
||||
|
||||
public List<String> getCategoryOneOf() {
|
||||
public List<Integer> getCategoryOneOf() {
|
||||
return categoryOneOf;
|
||||
}
|
||||
|
||||
public void setCategoryOneOf(List<String> categoryOneOf) {
|
||||
public void setCategoryOneOf(List<Integer> categoryOneOf) {
|
||||
this.categoryOneOf = categoryOneOf;
|
||||
}
|
||||
|
||||
public List<String> getLicenceOneOf() {
|
||||
public List<Integer> getLicenceOneOf() {
|
||||
return licenceOneOf;
|
||||
}
|
||||
|
||||
public void setLicenceOneOf(List<String> licenceOneOf) {
|
||||
public void setLicenceOneOf(List<Integer> licenceOneOf) {
|
||||
this.licenceOneOf = licenceOneOf;
|
||||
}
|
||||
|
||||
@ -159,10 +170,11 @@ class SepiaSearch implements Parcelable {
|
||||
dest.writeString(this.count);
|
||||
dest.writeString(this.search);
|
||||
dest.writeInt(this.durationMax);
|
||||
dest.writeInt(this.durationMin);
|
||||
dest.writeLong(this.startDate != null ? this.startDate.getTime() : -1);
|
||||
dest.writeStringList(this.boostLanguages);
|
||||
dest.writeStringList(this.categoryOneOf);
|
||||
dest.writeStringList(this.licenceOneOf);
|
||||
dest.writeList(this.categoryOneOf);
|
||||
dest.writeList(this.licenceOneOf);
|
||||
dest.writeStringList(this.tagsOneOf);
|
||||
dest.writeStringList(this.tagsAllOf);
|
||||
dest.writeByte(this.nsfw ? (byte) 1 : (byte) 0);
|
||||
@ -177,18 +189,21 @@ class SepiaSearch implements Parcelable {
|
||||
this.count = in.readString();
|
||||
this.search = in.readString();
|
||||
this.durationMax = in.readInt();
|
||||
this.durationMin = in.readInt();
|
||||
long tmpStartDate = in.readLong();
|
||||
this.startDate = tmpStartDate == -1 ? null : new Date(tmpStartDate);
|
||||
this.boostLanguages = in.createStringArrayList();
|
||||
this.categoryOneOf = in.createStringArrayList();
|
||||
this.licenceOneOf = in.createStringArrayList();
|
||||
this.categoryOneOf = new ArrayList<>();
|
||||
in.readList(this.categoryOneOf, Integer.class.getClassLoader());
|
||||
this.licenceOneOf = new ArrayList<>();
|
||||
in.readList(this.licenceOneOf, Integer.class.getClassLoader());
|
||||
this.tagsOneOf = in.createStringArrayList();
|
||||
this.tagsAllOf = in.createStringArrayList();
|
||||
this.nsfw = in.readByte() != 0;
|
||||
this.sort = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SepiaSearch> CREATOR = new Parcelable.Creator<SepiaSearch>() {
|
||||
public static final Creator<SepiaSearch> CREATOR = new Creator<SepiaSearch>() {
|
||||
@Override
|
||||
public SepiaSearch createFromParcel(Parcel source) {
|
||||
return new SepiaSearch(source);
|
||||
|
@ -0,0 +1,319 @@
|
||||
package app.fedilab.fedilabtube.fragment;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* TubeLab 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 TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.fedilabtube.R;
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
|
||||
import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter;
|
||||
import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import app.fedilab.fedilabtube.viewmodel.SepiaSearchVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
public class DisplaySepiaSearchFragment extends Fragment implements AccountsHorizontalListAdapter.EventListener {
|
||||
|
||||
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
private GridLayoutManager gLayoutManager;
|
||||
private boolean flag_loading;
|
||||
private Context context;
|
||||
private PeertubeAdapter peertubeAdapater;
|
||||
private String max_id;
|
||||
private List<VideoData.Video> peertubes;
|
||||
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
|
||||
private boolean firstLoad;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private SharedPreferences sharedpreferences;
|
||||
private TextView textviewNoActionText;
|
||||
private View rootView;
|
||||
private RecyclerView lv_status;
|
||||
private SepiaSearchVM viewModelSearch;
|
||||
|
||||
public DisplaySepiaSearchFragment() {
|
||||
}
|
||||
|
||||
private SepiaSearch sepiaSearchVideo;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
rootView = inflater.inflate(R.layout.fragment_video, container, false);
|
||||
|
||||
|
||||
peertubes = new ArrayList<>();
|
||||
context = getContext();
|
||||
Bundle bundle = this.getArguments();
|
||||
if (bundle != null) {
|
||||
sepiaSearchVideo = bundle.getParcelable("sepiaSearchVideo");
|
||||
}
|
||||
max_id = "0";
|
||||
lv_status = rootView.findViewById(R.id.lv_status);
|
||||
flag_loading = true;
|
||||
firstLoad = true;
|
||||
|
||||
assert context != null;
|
||||
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
|
||||
|
||||
mainLoader = rootView.findViewById(R.id.loader);
|
||||
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
|
||||
textviewNoAction = rootView.findViewById(R.id.no_action);
|
||||
textviewNoActionText = rootView.findViewById(R.id.no_action_text);
|
||||
mainLoader.setVisibility(View.VISIBLE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
|
||||
peertubeAdapater = new PeertubeAdapter(this.peertubes);
|
||||
lv_status.setAdapter(peertubeAdapater);
|
||||
|
||||
|
||||
if (!Helper.isTablet(context)) {
|
||||
mLayoutManager = new LinearLayoutManager(context);
|
||||
lv_status.setLayoutManager(mLayoutManager);
|
||||
} else {
|
||||
gLayoutManager = new GridLayoutManager(context, 2);
|
||||
int spanCount = (int) Helper.convertDpToPixel(2, context);
|
||||
int spacing = (int) Helper.convertDpToPixel(5, context);
|
||||
lv_status.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, true));
|
||||
lv_status.setLayoutManager(gLayoutManager);
|
||||
}
|
||||
viewModelSearch = new ViewModelProvider(DisplaySepiaSearchFragment.this).get(SepiaSearchVM.class);
|
||||
swipeRefreshLayout.setOnRefreshListener(this::pullToRefresh);
|
||||
|
||||
|
||||
|
||||
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
if (mLayoutManager != null) {
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if (dy > 0) {
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
|
||||
if (!flag_loading) {
|
||||
flag_loading = true;
|
||||
loadTimeline();
|
||||
nextElementLoader.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
} else if (gLayoutManager != null) {
|
||||
int firstVisibleItem = gLayoutManager.findFirstVisibleItemPosition();
|
||||
if (dy > 0) {
|
||||
int visibleItemCount = gLayoutManager.getChildCount();
|
||||
int totalItemCount = gLayoutManager.getItemCount();
|
||||
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
|
||||
if (!flag_loading) {
|
||||
flag_loading = true;
|
||||
loadTimeline();
|
||||
nextElementLoader.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
loadTimeline();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setEnabled(false);
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
swipeRefreshLayout.clearAnimation();
|
||||
}
|
||||
if (getActivity() != null) {
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null && getView() != null) {
|
||||
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance) {
|
||||
super.onCreate(saveInstance);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(@NotNull Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
private void manageVIewVideos(VideoData videoData) {
|
||||
//hide loaders
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
//handle other API error
|
||||
if (videoData == null || videoData.data == null) {
|
||||
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
flag_loading = false;
|
||||
return;
|
||||
}
|
||||
int previousPosition = this.peertubes.size();
|
||||
if (max_id == null)
|
||||
max_id = "0";
|
||||
int videoPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE);
|
||||
max_id = String.valueOf(Integer.parseInt(max_id) + videoPerPage);
|
||||
this.peertubes.addAll(videoData.data);
|
||||
//If no item were inserted previously the adapter is created
|
||||
if (previousPosition == 0) {
|
||||
peertubeAdapater = new PeertubeAdapter(this.peertubes);
|
||||
lv_status.setAdapter(peertubeAdapater);
|
||||
} else
|
||||
peertubeAdapater.notifyItemRangeInserted(previousPosition, videoData.data.size());
|
||||
//remove handlers
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
if (firstLoad && (videoData.data== null || videoData.data.size() == 0)) {
|
||||
textviewNoActionText.setText(R.string.no_video_to_display);
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
flag_loading = false;
|
||||
firstLoad = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (lv_status != null) {
|
||||
try {
|
||||
lv_status.setAdapter(null);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
super.onDestroyView();
|
||||
rootView = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
swipeRefreshLayout.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
public void scrollToTop() {
|
||||
if (mLayoutManager != null) {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0);
|
||||
} else if (gLayoutManager != null) {
|
||||
gLayoutManager.scrollToPositionWithOffset(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void pullToRefresh() {
|
||||
int size = peertubes.size();
|
||||
peertubes.clear();
|
||||
peertubes = new ArrayList<>();
|
||||
peertubeAdapater.notifyItemRangeRemoved(0, size);
|
||||
loadTimeline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(String forAccount) {
|
||||
pullToRefresh();
|
||||
}
|
||||
|
||||
private void loadTimeline() {
|
||||
viewModelSearch.sepiaSearch(sepiaSearchVideo).observe(this.requireActivity(), this::manageVIewVideos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private int spanCount;
|
||||
private int spacing;
|
||||
private boolean includeEdge;
|
||||
|
||||
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
|
||||
this.spanCount = spanCount;
|
||||
this.spacing = spacing;
|
||||
this.includeEdge = includeEdge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(@NotNull Rect outRect, @NotNull View view, RecyclerView parent, @NotNull RecyclerView.State state) {
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
int column = position % spanCount;
|
||||
|
||||
if (includeEdge) {
|
||||
outRect.left = spacing - column * spacing / spanCount;
|
||||
outRect.right = (column + 1) * spacing / spanCount;
|
||||
|
||||
if (position < spanCount) {
|
||||
outRect.top = spacing;
|
||||
}
|
||||
outRect.bottom = spacing;
|
||||
} else {
|
||||
outRect.left = column * spacing / spanCount;
|
||||
outRect.right = spacing - (column + 1) * spacing / spanCount;
|
||||
if (position >= spanCount) {
|
||||
outRect.top = spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -119,7 +119,6 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
|
||||
RecyclerView lv_accounts = rootView.findViewById(R.id.lv_accounts);
|
||||
Button display_all = rootView.findViewById(R.id.display_all);
|
||||
top_account_container = rootView.findViewById(R.id.top_account_container);
|
||||
max_id = null;
|
||||
max_id_accounts = null;
|
||||
flag_loading = true;
|
||||
firstLoad = true;
|
||||
|
@ -0,0 +1,58 @@
|
||||
package app.fedilab.fedilabtube.viewmodel;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* TubeLab 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 TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import app.fedilab.fedilabtube.client.RetrofitSepiaSearchAPI;
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
|
||||
|
||||
|
||||
public class SepiaSearchVM extends AndroidViewModel {
|
||||
private MutableLiveData<VideoData> apiResponseMutableLiveData;
|
||||
|
||||
public SepiaSearchVM(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
public LiveData<VideoData> sepiaSearch(SepiaSearch sepiaSearch) {
|
||||
apiResponseMutableLiveData = new MutableLiveData<>();
|
||||
getVideos(sepiaSearch);
|
||||
return apiResponseMutableLiveData;
|
||||
}
|
||||
|
||||
private void getVideos(SepiaSearch sepiaSearch) {
|
||||
Context _mContext = getApplication().getApplicationContext();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
VideoData videoData = new RetrofitSepiaSearchAPI(_mContext).getVideos(sepiaSearch);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(videoData);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/header"
|
||||
android:animateLayoutChanges="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
<com.mancj.materialsearchbar.MaterialSearchBar
|
||||
@ -88,6 +89,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/filter_elements"
|
||||
android:visibility="gone"
|
||||
android:animateLayoutChanges="true"
|
||||
app:layout_constraintTop_toBottomOf="@+id/filter"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
@ -141,6 +144,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_published_date_label"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
<RadioGroup
|
||||
android:id="@+id/radio_date"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -191,6 +195,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration_label"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
<RadioGroup
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
@ -225,53 +230,48 @@
|
||||
android:text="@string/category"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/sepia_element_license_label"
|
||||
android:id="@+id/sepia_element_category_label"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/sepia_element_license"
|
||||
android:text="@string/license"
|
||||
app:layout_constraintStart_toEndOf="@+id/sepia_element_category_label"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration"
|
||||
app:layout_constraintEnd_toStartOf="@+id/sepia_element_language_label"
|
||||
android:id="@+id/sepia_element_license_label"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/sepia_element_language"
|
||||
android:text="@string/language"
|
||||
app:layout_constraintStart_toEndOf="@+id/sepia_element_license_label"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:id="@+id/sepia_element_language_label"
|
||||
/>
|
||||
<Spinner
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_category_label"
|
||||
app:layout_constraintStart_toStartOf="@+id/sepia_element_category_label"
|
||||
app:layout_constraintStart_toEndOf="@+id/sepia_element_category_label"
|
||||
android:id="@+id/sepia_element_category"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/sepia_element_license"
|
||||
android:text="@string/license"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_category"
|
||||
android:id="@+id/sepia_element_license_label"
|
||||
/>
|
||||
<Spinner
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/category"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_license_label"
|
||||
app:layout_constraintStart_toStartOf="@+id/sepia_element_license_label"
|
||||
app:layout_constraintEnd_toEndOf="@+id/sepia_element_license_label"
|
||||
android:id="@+id/sepia_element_license"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/sepia_element_language"
|
||||
android:text="@string/language"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_license"
|
||||
android:id="@+id/sepia_element_language_label"
|
||||
/>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/category"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_language_label"
|
||||
app:layout_constraintStart_toStartOf="@+id/sepia_element_language_label"
|
||||
app:layout_constraintEnd_toEndOf="@+id/sepia_element_language_label"
|
||||
android:id="@+id/sepia_element_language"
|
||||
/>
|
||||
|
||||
@ -281,7 +281,7 @@
|
||||
android:labelFor="@+id/sepia_element_all_of_tags"
|
||||
android:text="@string/all_of_these_tags"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_category"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sepia_element_language"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:id="@+id/sepia_element_all_of_tags_label"
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user