diff --git a/app/build.gradle b/app/build.gradle
index ef4b0f3..1a28ad2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9bb01d4..cd8d641 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,6 +27,12 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/mobilizon/InstancePickerActivity.java b/app/src/main/java/app/fedilab/mobilizon/InstancePickerActivity.java
new file mode 100644
index 0000000..2375ab0
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/InstancePickerActivity.java
@@ -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 . */
+
+
+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 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 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);
+ }
+}
diff --git a/app/src/main/java/app/fedilab/mobilizon/MainActivity.java b/app/src/main/java/app/fedilab/mobilizon/MainActivity.java
index 80ff257..ab9aa4a 100644
--- a/app/src/main/java/app/fedilab/mobilizon/MainActivity.java
+++ b/app/src/main/java/app/fedilab/mobilizon/MainActivity.java
@@ -61,6 +61,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private WebView main_webview;
private FrameLayout webview_container;
private ValueCallback 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();
}
diff --git a/app/src/main/java/app/fedilab/mobilizon/client/InstancesService.java b/app/src/main/java/app/fedilab/mobilizon/client/InstancesService.java
new file mode 100644
index 0000000..d43da4f
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/client/InstancesService.java
@@ -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 . */
+import app.fedilab.mobilizon.client.entities.data.InstanceData;
+import retrofit2.Call;
+import retrofit2.http.GET;
+import retrofit2.http.Query;
+
+interface InstancesService {
+
+
+ @GET("instances")
+ Call getInstances(
+ @Query("start") String maxId,
+ @Query("count") String count,
+ @Query("search") String search,
+ @Query("sort") String sort);
+
+}
diff --git a/app/src/main/java/app/fedilab/mobilizon/client/RetrofitInstancesAPI.java b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitInstancesAPI.java
new file mode 100644
index 0000000..5556a4f
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitInstancesAPI.java
@@ -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 . */
+
+
+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 instanceDataCall = instancesService.getInstances(search.getStart(), search.getCount(), search.getSearch(), search.getSort());
+ Response response = instanceDataCall.execute();
+ if (response.isSuccessful() && response.body() != null) {
+ return response.body();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java
index 6ef34bb..9bdc3f9 100644
--- a/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java
+++ b/app/src/main/java/app/fedilab/mobilizon/client/RetrofitMobilizonAPI.java
@@ -27,7 +27,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitMobilizonAPI {
- private String finalUrl;
+ private final String finalUrl;
public RetrofitMobilizonAPI(String instance) {
diff --git a/app/src/main/java/app/fedilab/mobilizon/client/entities/Search.java b/app/src/main/java/app/fedilab/mobilizon/client/entities/Search.java
new file mode 100644
index 0000000..9354a78
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/client/entities/Search.java
@@ -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 . */
+
+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;
+ }
+}
diff --git a/app/src/main/java/app/fedilab/mobilizon/client/entities/data/InstanceData.java b/app/src/main/java/app/fedilab/mobilizon/client/entities/data/InstanceData.java
new file mode 100644
index 0000000..5168f5c
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/client/entities/data/InstanceData.java
@@ -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 . */
+
+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 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 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 getLanguages() {
+ return languages;
+ }
+
+ public void setLanguages(List 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;
+ }
+ }
+}
+
diff --git a/app/src/main/java/app/fedilab/mobilizon/drawer/InstanceAdapter.java b/app/src/main/java/app/fedilab/mobilizon/drawer/InstanceAdapter.java
new file mode 100644
index 0000000..2dd3a52
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/drawer/InstanceAdapter.java
@@ -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 . */
+
+
+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 {
+
+ private final List instances;
+
+ private Context context;
+
+ public InstanceAdapter(List 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/mobilizon/viewmodel/SearchInstancesVM.java b/app/src/main/java/app/fedilab/mobilizon/viewmodel/SearchInstancesVM.java
new file mode 100644
index 0000000..b7a2570
--- /dev/null
+++ b/app/src/main/java/app/fedilab/mobilizon/viewmodel/SearchInstancesVM.java
@@ -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 . */
+
+
+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 instanceDataMutableLiveData;
+
+
+ public LiveData 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();
+ }
+
+}
diff --git a/app/src/main/res/drawable/ic_baseline_forum_24.xml b/app/src/main/res/drawable/ic_baseline_forum_24.xml
new file mode 100644
index 0000000..14f298d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_forum_24.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_instance_picker.xml b/app/src/main/res/layout/activity_instance_picker.xml
new file mode 100644
index 0000000..715d7a0
--- /dev/null
+++ b/app/src/main/res/layout/activity_instance_picker.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index be60fc1..df6a6d6 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,4 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml
index 127e129..e673e4d 100644
--- a/app/src/main/res/layout/nav_header_main.xml
+++ b/app/src/main/res/layout/nav_header_main.xml
@@ -1,18 +1,19 @@
-
+
About the app (Release %1$s)
This permission is used for searching events next to your location.Settings
+ Search among instances
+ No results.
+ Instances picker
+ Pick this instance
+ Local events: %1$s
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 21d9ced..0de42dc 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -16,4 +16,6 @@
+
+
\ No newline at end of file