From fe610b7ecb75d21036d2aacf1ac2990968353f97 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 27 Oct 2020 12:06:50 +0100 Subject: [PATCH] Add instances picker --- app/build.gradle | 8 +- app/src/main/AndroidManifest.xml | 6 + .../mobilizon/InstancePickerActivity.java | 132 ++++++++++ .../app/fedilab/mobilizon/MainActivity.java | 6 +- .../mobilizon/client/InstancesService.java | 31 +++ .../client/RetrofitInstancesAPI.java | 57 +++++ .../client/RetrofitMobilizonAPI.java | 2 +- .../mobilizon/client/entities/Search.java | 55 ++++ .../client/entities/data/InstanceData.java | 239 ++++++++++++++++++ .../mobilizon/drawer/InstanceAdapter.java | 130 ++++++++++ .../viewmodel/SearchInstancesVM.java | 56 ++++ .../res/drawable/ic_baseline_forum_24.xml | 5 + .../res/layout/activity_instance_picker.xml | 123 +++++++++ app/src/main/res/layout/activity_main.xml | 16 ++ app/src/main/res/layout/content_main.xml | 16 ++ app/src/main/res/layout/drawer_instance.xml | 99 ++++++++ app/src/main/res/layout/nav_header_main.xml | 13 +- app/src/main/res/layout/popup_about.xml | 16 ++ app/src/main/res/values/strings.xml | 5 + app/src/main/res/values/styles.xml | 2 + 20 files changed, 1006 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/app/fedilab/mobilizon/InstancePickerActivity.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/client/InstancesService.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/client/RetrofitInstancesAPI.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/client/entities/Search.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/client/entities/data/InstanceData.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/drawer/InstanceAdapter.java create mode 100644 app/src/main/java/app/fedilab/mobilizon/viewmodel/SearchInstancesVM.java create mode 100644 app/src/main/res/drawable/ic_baseline_forum_24.xml create mode 100644 app/src/main/res/layout/activity_instance_picker.xml create mode 100644 app/src/main/res/layout/drawer_instance.xml 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 @@ + + + + + + + + + + + + + + + + + + + + + +