From 9ee638b868970c905cd43343712d0a1cab4d5ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schu=CC=88ller?= Date: Sun, 17 Feb 2019 16:26:17 +0100 Subject: [PATCH] server selection, wip --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 60 +++---- .../activity/SelectServerActivity.java | 159 ++++++++++++++---- .../peertube/activity/VideoListActivity.java | 7 + .../peertube/adapter/ServerAdapter.java | 119 +++++++++++++ .../peertube/helper/APIUrlHelper.java | 4 + .../net/schueller/peertube/model/Server.java | 6 +- .../res/layout/activity_select_server.xml | 9 - .../res/layout/activity_server_selection.xml | 34 ++++ app/src/main/res/layout/row_server.xml | 45 +++++ app/src/main/res/menu/menu_top_videolist.xml | 7 + app/src/main/res/values/strings.xml | 1 + 12 files changed, 373 insertions(+), 80 deletions(-) create mode 100644 app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java delete mode 100644 app/src/main/res/layout/activity_select_server.xml create mode 100644 app/src/main/res/layout/activity_server_selection.xml create mode 100644 app/src/main/res/layout/row_server.xml diff --git a/app/build.gradle b/app/build.gradle index 355efc8..f2382b2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,4 +78,6 @@ android { dependencies { implementation 'com.android.support.constraint:constraint-layout:+' + implementation 'androidx.appcompat:appcompat:1.0.0-beta01' + implementation 'androidx.constraintlayout:constraintlayout:1.1.2' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 073b0ba..5250d9f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,73 +2,65 @@ - - - - - - - + + - - + tools:ignore="GoogleAppIndexingWarning"> + + + - + android:resource="@xml/searchable"> + android:label="@string/title_activity_login" + android:theme="@style/AppTheme.NoActionBar" /> + android:launchMode="singleTop" + android:theme="@style/AppTheme.NoActionBar" /> - - - - + + - - - - + android:theme="@style/AppTheme.NoActionBar" /> + - - \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java b/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java index 4a8789e..539d28f 100644 --- a/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java @@ -1,61 +1,152 @@ -/* - * Copyright 2018 Stefan Schüller - * - * License: GPL-3.0+ - * 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. - * - * This program 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 this program. If not, see . - */ - package net.schueller.peertube.activity; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import android.os.Bundle; - -import net.schueller.peertube.R; -import net.schueller.peertube.model.ServerList; -import net.schueller.peertube.network.GetServerListDataService; -import net.schueller.peertube.network.RetrofitInstance; - +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import net.schueller.peertube.R; +import net.schueller.peertube.adapter.ServerAdapter; +import net.schueller.peertube.adapter.VideoAdapter; +import net.schueller.peertube.helper.APIUrlHelper; +import net.schueller.peertube.model.ServerList; +import net.schueller.peertube.model.VideoList; +import net.schueller.peertube.network.GetServerListDataService; +import net.schueller.peertube.network.GetVideoDataService; +import net.schueller.peertube.network.RetrofitInstance; + +import java.util.ArrayList; + public class SelectServerActivity extends AppCompatActivity { + private ServerAdapter serverAdapter; + private SwipeRefreshLayout swipeRefreshLayout; + + private int currentStart = 0; + private int count = 12; + + private TextView emptyView; + private RecyclerView recyclerView; + + private boolean isLoading = false; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_select_server); + setContentView(R.layout.activity_server_selection); - // get list of peertube servers + loadList(); + } - // TODO: Get here via settings, get data from API, add to adapter and show in recycle view, upon selection fill settings field - GetServerListDataService service = RetrofitInstance.getRetrofitInstance("https://instances.joinpeertube.org/api/v1/").create(GetServerListDataService.class); - Call call = service.getInstancesData(0, 500); - call.enqueue(new Callback() { + private void loadList() { + + recyclerView = findViewById(R.id.serverRecyclerView); + swipeRefreshLayout = findViewById(R.id.serversSwipeRefreshLayout); + + emptyView = findViewById(R.id.empty_server_selection_view); + + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(SelectServerActivity.this); + recyclerView.setLayoutManager(layoutManager); + + serverAdapter = new ServerAdapter(new ArrayList<>(), SelectServerActivity.this); + recyclerView.setAdapter(serverAdapter); + + loadServers(currentStart, count); + + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - // response.body().getVideoArrayList(); + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); } @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + // is at end of list? + if (!recyclerView.canScrollVertically(RecyclerView.FOCUS_DOWN)) { + if (!isLoading) { + currentStart = currentStart + count; + loadServers(currentStart, count); + } + } + } + + } + }); + + swipeRefreshLayout.setOnRefreshListener(() -> { + // Refresh items + if (!isLoading) { + currentStart = 0; + loadServers(currentStart, count); } }); } + + + + private void loadServers(int start, int count) { + isLoading = true; + + GetServerListDataService service = RetrofitInstance.getRetrofitInstance( + APIUrlHelper.getServerIndexUrl(SelectServerActivity.this) + ).create(GetServerListDataService.class); + + + Call call; + + call = service.getInstancesData(start, count); + + Log.d("URL Called", call.request().url() + ""); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + if (currentStart == 0) { + serverAdapter.clearData(); + } + + if (response.body() != null) { + serverAdapter.setData(response.body().getServerArrayList()); + } + + // no results show no results message + if (currentStart == 0 && serverAdapter.getItemCount() == 0) { + emptyView.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); + + } else { + emptyView.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); + } + + isLoading = false; + swipeRefreshLayout.setRefreshing(false); + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.wtf("err", t.fillInStackTrace()); + Toast.makeText(SelectServerActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); + isLoading = false; + swipeRefreshLayout.setRefreshing(false); + } + }); + + } } diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index f851b73..d4950e9 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -128,6 +128,9 @@ public class VideoListActivity extends CommonActivity { menu.findItem(R.id.action_account).setIcon( new IconicsDrawable(this, FontAwesome.Icon.faw_user_circle).actionBar()); + menu.findItem(R.id.action_server_selection).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_server).actionBar()); + MenuItem searchMenuItem = menu.findItem(R.id.action_search); searchMenuItem.setIcon( @@ -200,6 +203,10 @@ public class VideoListActivity extends CommonActivity { this.startActivity(intentMe); } return false; + case R.id.action_server_selection: + Intent intentServer = new Intent(this, SelectServerActivity.class); + this.startActivity(intentServer); + return false; default: break; } diff --git a/app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java b/app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java new file mode 100644 index 0000000..0772a64 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java @@ -0,0 +1,119 @@ +/* + * Copyright 2018 Stefan Schüller + * + * License: GPL-3.0+ + * 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. + * + * This program 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 this program. If not, see . + */ +package net.schueller.peertube.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + + +import net.schueller.peertube.R; +import net.schueller.peertube.helper.APIUrlHelper; +import net.schueller.peertube.model.Server; + +import java.util.ArrayList; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + + +public class ServerAdapter extends RecyclerView.Adapter { + + + private ArrayList serverList; + private Context context; + private String baseUrl; + + public ServerAdapter(ArrayList serverList, Context context) { + this.serverList = serverList; + this.context = context; + } + + @NonNull + @Override + public AccountViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); + View view = layoutInflater.inflate(R.layout.row_server, parent, false); + + baseUrl = APIUrlHelper.getUrl(context); + + return new AccountViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull AccountViewHolder holder, int position) { + + holder.name.setText(serverList.get(position).getName()); + holder.host.setText(serverList.get(position).getHost()); + holder.shortDescription.setText(serverList.get(position).getShortDescription()); +// +// +// holder.moreButton.setText(R.string.video_more_icon); +// new Iconics.IconicsBuilder().ctx(context).on(holder.moreButton).build(); +// +// holder.moreButton.setOnClickListener(v -> { +// +// PopupMenu popup = new PopupMenu(context, v); +// popup.setOnMenuItemClickListener(menuItem -> { +// switch (menuItem.getItemId()) { +// case R.id.menu_share: +// Intents.Share(context, serverList.get(position)); +// return true; +// default: +// return false; +// } +// }); +// popup.inflate(R.menu.menu_video_row_mode); +// popup.show(); +// +// }); + + } + + public void setData(ArrayList data) { + serverList.addAll(data); + this.notifyDataSetChanged(); + } + + public void clearData() { + serverList.clear(); + this.notifyDataSetChanged(); + } + + @Override + public int getItemCount() { + return serverList.size(); + } + + class AccountViewHolder extends RecyclerView.ViewHolder { + + TextView name, host, shortDescription; + + AccountViewHolder(View itemView) { + super(itemView); + name = itemView.findViewById(R.id.name); + host = itemView.findViewById(R.id.host); + shortDescription = itemView.findViewById(R.id.shortDescription); + + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java index 4a4c06a..b632f42 100644 --- a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java +++ b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java @@ -44,4 +44,8 @@ public class APIUrlHelper{ public static String getShareUrl(Context context, String videoUuid) { return APIUrlHelper.getUrl(context) + "/videos/watch/" + videoUuid; } + + public static String getServerIndexUrl(Context context) { + return "https://instances.joinpeertube.org/api/v1/"; + } } diff --git a/app/src/main/java/net/schueller/peertube/model/Server.java b/app/src/main/java/net/schueller/peertube/model/Server.java index 4d14404..77e1ed6 100644 --- a/app/src/main/java/net/schueller/peertube/model/Server.java +++ b/app/src/main/java/net/schueller/peertube/model/Server.java @@ -25,7 +25,7 @@ public class Server { private String shortDescription; private String version; private Boolean signupAllowed; - private Integer userVideoQuota; + private Double userVideoQuota; private Integer totalUsers; private Integer totalVideos; private Integer totalLocalVideos; @@ -81,11 +81,11 @@ public class Server { this.signupAllowed = signupAllowed; } - public Integer getUserVideoQuota() { + public Double getUserVideoQuota() { return userVideoQuota; } - public void setUserVideoQuota(Integer userVideoQuota) { + public void setUserVideoQuota(Double userVideoQuota) { this.userVideoQuota = userVideoQuota; } diff --git a/app/src/main/res/layout/activity_select_server.xml b/app/src/main/res/layout/activity_select_server.xml deleted file mode 100644 index 71beae8..0000000 --- a/app/src/main/res/layout/activity_select_server.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_server_selection.xml b/app/src/main/res/layout/activity_server_selection.xml new file mode 100644 index 0000000..f78ddc0 --- /dev/null +++ b/app/src/main/res/layout/activity_server_selection.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_server.xml b/app/src/main/res/layout/row_server.xml new file mode 100644 index 0000000..efeac65 --- /dev/null +++ b/app/src/main/res/layout/row_server.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_top_videolist.xml b/app/src/main/res/menu/menu_top_videolist.xml index 121e62d..e8a536e 100644 --- a/app/src/main/res/menu/menu_top_videolist.xml +++ b/app/src/main/res/menu/menu_top_videolist.xml @@ -26,4 +26,11 @@ android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" app:showAsAction="ifRoom" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8db3e6b..86c214b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -344,5 +344,6 @@ none like dislike + Select Server