Add instances picker
This commit is contained in:
parent
11fec8c4ac
commit
fe610b7ecb
|
@ -25,6 +25,10 @@ android {
|
|||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation'
|
||||
checkReleaseBuilds false
|
||||
|
@ -44,8 +48,8 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
||||
implementation 'androidx.navigation:navigation-ui:2.3.0'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.3.1'
|
||||
implementation 'androidx.navigation:navigation-ui:2.3.1'
|
||||
testImplementation 'junit:junit:4.13'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".InstancePickerActivity"
|
||||
android:label="@string/instances_picker"
|
||||
android:configChanges="orientation|screenSize|layoutDirection"
|
||||
android:theme="@style/AppTheme"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,132 @@
|
|||
package app.fedilab.mobilizon;
|
||||
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.mobilizon.client.entities.Search;
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData;
|
||||
import app.fedilab.mobilizon.databinding.ActivityInstancePickerBinding;
|
||||
import app.fedilab.mobilizon.drawer.InstanceAdapter;
|
||||
import app.fedilab.mobilizon.viewmodel.SearchInstancesVM;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class InstancePickerActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private ActivityInstancePickerBinding binding;
|
||||
private List<InstanceData.Instance> instances;
|
||||
private boolean flag_loading;
|
||||
private String max_id;
|
||||
private Search search;
|
||||
private InstanceAdapter instanceAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding = ActivityInstancePickerBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
search = new Search();
|
||||
search.setCount("10");
|
||||
search.setStart(max_id);
|
||||
search.setSort("-createdAt");
|
||||
|
||||
max_id = "0";
|
||||
setContentView(R.layout.activity_instance_picker);
|
||||
instances = new ArrayList<>();
|
||||
|
||||
binding.loader.setVisibility(View.VISIBLE);
|
||||
flag_loading = true;
|
||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(InstancePickerActivity.this);
|
||||
|
||||
SearchInstancesVM searchInstancesVM = new ViewModelProvider(InstancePickerActivity.this).get(SearchInstancesVM.class);
|
||||
|
||||
instanceAdapter = new InstanceAdapter(instances);
|
||||
binding.lvInstances.setAdapter(instanceAdapter);
|
||||
binding.lvInstances.setLayoutManager(mLayoutManager);
|
||||
|
||||
binding.lvInstances.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if (dy > 0) {
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
if (firstVisibleItem + visibleItemCount == totalItemCount) {
|
||||
if (!flag_loading) {
|
||||
flag_loading = true;
|
||||
search.setStart(max_id);
|
||||
searchInstancesVM.get(search).observe(InstancePickerActivity.this, instanceData -> manageVIewInstance(instanceData));
|
||||
binding.loadingNextInstances.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
binding.loadingNextInstances.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchInstancesVM.get(search).observe(InstancePickerActivity.this, this::manageVIewInstance);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
public void manageVIewInstance(InstanceData instanceData) {
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.loadingNextInstances.setVisibility(View.GONE);
|
||||
if (instanceData == null || instanceData.data.size() == 0) {
|
||||
binding.noAction.setVisibility(View.VISIBLE);
|
||||
binding.lvInstances.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
int oldPosition = this.instances.size();
|
||||
List<InstanceData.Instance> instances = instanceData.data;
|
||||
this.instances.addAll(instances);
|
||||
instanceAdapter.notifyItemRangeInserted(oldPosition, instances.size());
|
||||
binding.noAction.setVisibility(View.GONE);
|
||||
binding.lvInstances.setVisibility(View.VISIBLE);
|
||||
max_id = String.valueOf(Integer.parseInt(max_id) + 10);
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
private WebView main_webview;
|
||||
private FrameLayout webview_container;
|
||||
private ValueCallback<Uri[]> mFilePathCallback;
|
||||
private static final int PICK_INSTANCE = 546;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -359,9 +360,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
}).start());
|
||||
//TODO: uncomment and add support for picking instances when available
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
/*alt_bld.setNeutralButton(R.string.help, (dialog, which) -> {
|
||||
alt_bld.setNeutralButton(R.string.help, (dialog, which) -> {
|
||||
Intent intent = new Intent(MainActivity.this, InstancePickerActivity.class);
|
||||
startActivityForResult(intent, PICK_INSTANCE);
|
||||
});*/
|
||||
});
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package app.fedilab.mobilizon.client;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
interface InstancesService {
|
||||
|
||||
|
||||
@GET("instances")
|
||||
Call<InstanceData> getInstances(
|
||||
@Query("start") String maxId,
|
||||
@Query("count") String count,
|
||||
@Query("search") String search,
|
||||
@Query("sort") String sort);
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package app.fedilab.mobilizon.client;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import app.fedilab.mobilizon.client.entities.Search;
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class RetrofitInstancesAPI {
|
||||
|
||||
|
||||
private InstancesService init() {
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl("https://instances.joinmobilizon.org/api/v1")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
return retrofit.create(InstancesService.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get NodeInfo
|
||||
*
|
||||
* @return APIResponse
|
||||
*/
|
||||
public InstanceData search(Search search) {
|
||||
InstancesService instancesService = init();
|
||||
try {
|
||||
Call<InstanceData> instanceDataCall = instancesService.getInstances(search.getStart(), search.getCount(), search.getSearch(), search.getSort());
|
||||
Response<InstanceData> response = instanceDataCall.execute();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
return response.body();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
|||
public class RetrofitMobilizonAPI {
|
||||
|
||||
|
||||
private String finalUrl;
|
||||
private final String finalUrl;
|
||||
|
||||
|
||||
public RetrofitMobilizonAPI(String instance) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package app.fedilab.mobilizon.client.entities;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
public class Search {
|
||||
|
||||
private String start;
|
||||
private String count;
|
||||
private String search;
|
||||
private String sort;
|
||||
|
||||
public String getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(String start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public String getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(String count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getSearch() {
|
||||
return search;
|
||||
}
|
||||
|
||||
public void setSearch(String search) {
|
||||
this.search = search;
|
||||
}
|
||||
|
||||
public String getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(String sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
package app.fedilab.mobilizon.client.entities.data;
|
||||
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"unused", "RedundantSuppression"})
|
||||
public class InstanceData {
|
||||
|
||||
@SerializedName("total")
|
||||
public int total;
|
||||
@SerializedName("data")
|
||||
public List<Instance> data;
|
||||
|
||||
|
||||
public static class Instance {
|
||||
@SerializedName("country")
|
||||
private String country;
|
||||
@SerializedName("createdAt")
|
||||
private Date createdAt;
|
||||
@SerializedName("health")
|
||||
private int health;
|
||||
@SerializedName("host")
|
||||
private String host;
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
@SerializedName("languages")
|
||||
private List<Language> languages;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("shortDescription")
|
||||
private String shortDescription;
|
||||
@SerializedName("signupAllowed")
|
||||
private boolean signupAllowed;
|
||||
@SerializedName("supportsIPv6")
|
||||
private boolean supportsIPv6;
|
||||
@SerializedName("totalEvents")
|
||||
private int totalEvents;
|
||||
@SerializedName("totalGroups")
|
||||
private int totalGroups;
|
||||
@SerializedName("totalInstanceFollowers")
|
||||
private int totalInstanceFollowers;
|
||||
@SerializedName("totalInstanceFollowing")
|
||||
private int totalInstanceFollowing;
|
||||
@SerializedName("totalLocalEvents")
|
||||
private int totalLocalEvents;
|
||||
@SerializedName("totalLocalGroups")
|
||||
private int totalLocalGroups;
|
||||
@SerializedName("totalUsers")
|
||||
private int totalUsers;
|
||||
@SerializedName("version")
|
||||
private String version;
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public int getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public void setHealth(int health) {
|
||||
this.health = health;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Language> getLanguages() {
|
||||
return languages;
|
||||
}
|
||||
|
||||
public void setLanguages(List<Language> languages) {
|
||||
this.languages = languages;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getShortDescription() {
|
||||
return shortDescription;
|
||||
}
|
||||
|
||||
public void setShortDescription(String shortDescription) {
|
||||
this.shortDescription = shortDescription;
|
||||
}
|
||||
|
||||
public boolean isSignupAllowed() {
|
||||
return signupAllowed;
|
||||
}
|
||||
|
||||
public void setSignupAllowed(boolean signupAllowed) {
|
||||
this.signupAllowed = signupAllowed;
|
||||
}
|
||||
|
||||
public boolean isSupportsIPv6() {
|
||||
return supportsIPv6;
|
||||
}
|
||||
|
||||
public void setSupportsIPv6(boolean supportsIPv6) {
|
||||
this.supportsIPv6 = supportsIPv6;
|
||||
}
|
||||
|
||||
public int getTotalEvents() {
|
||||
return totalEvents;
|
||||
}
|
||||
|
||||
public void setTotalEvents(int totalEvents) {
|
||||
this.totalEvents = totalEvents;
|
||||
}
|
||||
|
||||
public int getTotalGroups() {
|
||||
return totalGroups;
|
||||
}
|
||||
|
||||
public void setTotalGroups(int totalGroups) {
|
||||
this.totalGroups = totalGroups;
|
||||
}
|
||||
|
||||
public int getTotalInstanceFollowers() {
|
||||
return totalInstanceFollowers;
|
||||
}
|
||||
|
||||
public void setTotalInstanceFollowers(int totalInstanceFollowers) {
|
||||
this.totalInstanceFollowers = totalInstanceFollowers;
|
||||
}
|
||||
|
||||
public int getTotalInstanceFollowing() {
|
||||
return totalInstanceFollowing;
|
||||
}
|
||||
|
||||
public void setTotalInstanceFollowing(int totalInstanceFollowing) {
|
||||
this.totalInstanceFollowing = totalInstanceFollowing;
|
||||
}
|
||||
|
||||
public int getTotalLocalEvents() {
|
||||
return totalLocalEvents;
|
||||
}
|
||||
|
||||
public void setTotalLocalEvents(int totalLocalEvents) {
|
||||
this.totalLocalEvents = totalLocalEvents;
|
||||
}
|
||||
|
||||
public int getTotalLocalGroups() {
|
||||
return totalLocalGroups;
|
||||
}
|
||||
|
||||
public void setTotalLocalGroups(int totalLocalGroups) {
|
||||
this.totalLocalGroups = totalLocalGroups;
|
||||
}
|
||||
|
||||
public int getTotalUsers() {
|
||||
return totalUsers;
|
||||
}
|
||||
|
||||
public void setTotalUsers(int totalUsers) {
|
||||
this.totalUsers = totalUsers;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Language {
|
||||
@SerializedName("displayName")
|
||||
private String displayName;
|
||||
@SerializedName("code")
|
||||
private String code;
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package app.fedilab.mobilizon.drawer;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.mobilizon.R;
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData;
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData.Instance;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
|
||||
|
||||
public class InstanceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final List<Instance> instances;
|
||||
|
||||
private Context context;
|
||||
|
||||
public InstanceAdapter(List<Instance> instances) {
|
||||
this.instances = instances;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
context = parent.getContext();
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_instance, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
final Instance instance = instances.get(position);
|
||||
final ViewHolder holder = (ViewHolder) viewHolder;
|
||||
|
||||
if (instance.getShortDescription() != null && instance.getShortDescription().trim().length() > 0) {
|
||||
holder.description.setText(instance.getShortDescription());
|
||||
holder.description.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.description.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.name.setText(instance.getName());
|
||||
holder.host.setText(instance.getHost());
|
||||
|
||||
|
||||
holder.version.setText(instance.getVersion());
|
||||
|
||||
StringBuilder languages = new StringBuilder();
|
||||
if (instance.getLanguages() != null && instance.getLanguages().size() > 0) {
|
||||
for (InstanceData.Language language : instance.getLanguages()) {
|
||||
languages.append(language.getDisplayName()).append(" ");
|
||||
}
|
||||
}
|
||||
if (languages.toString().trim().length() == 0) {
|
||||
holder.languages.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.languages.setText(languages);
|
||||
holder.languages.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
holder.local_events.setText(context.getString(R.string.local_events, String.valueOf(instance.getTotalLocalEvents())));
|
||||
|
||||
holder.pickup.setOnClickListener(v -> {
|
||||
Intent data = new Intent();
|
||||
String instanceHost = instance.getHost();
|
||||
data.setData(Uri.parse(instanceHost));
|
||||
((Activity) context).setResult(RESULT_OK, data);
|
||||
((Activity) context).finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return instances.size();
|
||||
}
|
||||
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
Button pickup;
|
||||
TextView name, host, description;
|
||||
TextView version, local_events, languages;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
pickup = itemView.findViewById(R.id.pickup);
|
||||
name = itemView.findViewById(R.id.name);
|
||||
host = itemView.findViewById(R.id.host);
|
||||
description = itemView.findViewById(R.id.description);
|
||||
local_events = itemView.findViewById(R.id.local_events);
|
||||
version = itemView.findViewById(R.id.version);
|
||||
languages = itemView.findViewById(R.id.languages);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package app.fedilab.mobilizon.viewmodel;
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mobilizon app
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mobilizon app 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 Mobilizon app; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import app.fedilab.mobilizon.client.RetrofitInstancesAPI;
|
||||
import app.fedilab.mobilizon.client.entities.Search;
|
||||
import app.fedilab.mobilizon.client.entities.data.InstanceData;
|
||||
|
||||
public class SearchInstancesVM extends ViewModel {
|
||||
|
||||
private MutableLiveData<InstanceData> instanceDataMutableLiveData;
|
||||
|
||||
|
||||
public LiveData<InstanceData> get(Search search) {
|
||||
instanceDataMutableLiveData = new MutableLiveData<>();
|
||||
searchInstances(search);
|
||||
return instanceDataMutableLiveData;
|
||||
}
|
||||
|
||||
|
||||
private void searchInstances(Search search) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
RetrofitInstancesAPI retrofitInstancesAPI = new RetrofitInstancesAPI();
|
||||
InstanceData instanceData = retrofitInstancesAPI.search(search);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> instanceDataMutableLiveData.setValue(instanceData);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal" 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="M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z"/>
|
||||
</vector>
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
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.
|
||||
|
||||
Mobilizon app 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 Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<androidx.drawerlayout.widget.DrawerLayout 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:layout_margin="@dimen/fab_margin">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".InstancePickerActivity">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/fab_margin">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/filters_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.SearchView
|
||||
app:queryHint="@string/search_instance_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:animateLayoutChanges="false"
|
||||
android:id="@+id/searchBar" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
<!-- Main Loader -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/loader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/filters_container">
|
||||
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
style="@style/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:SpinKit_Color="?colorAccent" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/filters_container">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/lv_instances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none" />
|
||||
<RelativeLayout
|
||||
android:id="@+id/no_action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:text="@string/no_results"
|
||||
android:textSize="25sp" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
<!-- Loader for next videos -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/loading_next_instances"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
style="@style/progressBottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:SpinKit_Color="?colorAccent" />
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -1,4 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
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.
|
||||
|
||||
Mobilizon app 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 Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<androidx.drawerlayout.widget.DrawerLayout 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"
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
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.
|
||||
|
||||
Mobilizon app 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 Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
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.
|
||||
|
||||
Mobilizon app 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 Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:divider="?android:dividerHorizontal"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="end">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/host"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
app:layout_constraintStart_toEndOf="@+id/name"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/local_events"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:drawablePadding="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_group_24"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/version" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/languages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:drawablePadding="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_forum_24"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/local_events" />
|
||||
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/pickup"
|
||||
style="@style/Base.Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:text="@string/pickup_instance"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/languages" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,18 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2017 Thomas Schneider
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Fedilab
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
Mobilizon app is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
see <http://www.gnu.org/licenses>
|
||||
You should have received a copy of the GNU General Public License along with Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 Thomas Schneider
|
||||
|
||||
This file is a part of Mobilizon app
|
||||
|
||||
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.
|
||||
|
||||
Mobilizon app 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 Mobilizon app; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -39,4 +39,9 @@
|
|||
<string name="about_the_app">About the app (Release %1$s)</string>
|
||||
<string name="permissions_message">This permission is used for searching events next to your location.</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="search_instance_hint">Search among instances</string>
|
||||
<string name="no_results">No results.</string>
|
||||
<string name="instances_picker">Instances picker</string>
|
||||
<string name="pickup_instance">Pick this instance</string>
|
||||
<string name="local_events">Local events: %1$s</string>
|
||||
</resources>
|
|
@ -16,4 +16,6 @@
|
|||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<style name="progress" parent="SpinKitView.Circle" />
|
||||
<style name="progressBottom" parent="SpinKitView.ThreeBounce" />
|
||||
</resources>
|
Loading…
Reference in New Issue