From a4864a71a87cca8e399011e01a786118231820ab Mon Sep 17 00:00:00 2001 From: Stefan Schueller Date: Sun, 6 Jan 2019 15:22:14 +0100 Subject: [PATCH] Account details and account video list added --- app/src/main/AndroidManifest.xml | 4 +- .../peertube/activity/AccountActivity.java | 337 +++++++++++++----- .../peertube/activity/LoginActivity.java | 6 +- .../peertube/activity/MeActivity.java | 162 +++++++++ .../peertube/activity/VideoListActivity.java | 7 +- .../peertube/adapter/ChannelAdapter.java | 175 +++++++++ .../peertube/adapter/VideoAdapter.java | 25 +- .../schueller/peertube/model/ChannelList.java | 33 ++ .../peertube/network/GetUserService.java | 17 + .../peertube/network/GetVideoDataService.java | 10 + app/src/main/res/layout/activity_account.xml | 209 +++++++++-- app/src/main/res/layout/activity_me.xml | 48 +++ .../main/res/layout/activity_video_list.xml | 2 +- app/src/main/res/layout/row_account_about.xml | 104 ++++++ .../main/res/layout/row_account_channels.xml | 104 ++++++ app/src/main/res/layout/row_account_video.xml | 104 ++++++ app/src/main/res/menu/menu_bottom_account.xml | 21 ++ ..._bottom.xml => menu_bottom_video_list.xml} | 0 ...menu_top_user.xml => menu_top_account.xml} | 0 app/src/main/res/values/strings.xml | 12 +- 20 files changed, 1248 insertions(+), 132 deletions(-) create mode 100644 app/src/main/java/net/schueller/peertube/activity/MeActivity.java create mode 100644 app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java create mode 100644 app/src/main/java/net/schueller/peertube/model/ChannelList.java create mode 100644 app/src/main/res/layout/activity_me.xml create mode 100644 app/src/main/res/layout/row_account_about.xml create mode 100644 app/src/main/res/layout/row_account_channels.xml create mode 100644 app/src/main/res/layout/row_account_video.xml create mode 100644 app/src/main/res/menu/menu_bottom_account.xml rename app/src/main/res/menu/{menu_bottom.xml => menu_bottom_video_list.xml} (100%) rename app/src/main/res/menu/{menu_top_user.xml => menu_top_account.xml} (100%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index de4a1d2..073b0ba 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -52,10 +52,12 @@ - + videosLanguages; + + private ChannelAdapter channelAdapter; + private VideoAdapter videoAdapter; + + private RecyclerView recyclerViewVideos; + private RecyclerView recyclerViewChannels; + + private SwipeRefreshLayout swipeRefreshLayoutVideos; + private SwipeRefreshLayout swipeRefreshLayoutChannels; + private CoordinatorLayout aboutView; + //private TextView emptyView; + + private Boolean isLoadingVideos; + + private GetUserService userService; + + private String displayNameAndHost; @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu_top_user, menu); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - // Set an icon in the ActionBar - menu.findItem(R.id.action_logout).setIcon( - new IconicsDrawable(this, FontAwesome.Icon.faw_sign_out_alt).actionBar()); + setContentView(R.layout.activity_account); - return true; - } + apiBaseURL = APIUrlHelper.getUrlWithVersion(this); + + userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); + + recyclerViewVideos = findViewById(R.id.account_video_recyclerView); + recyclerViewChannels = findViewById(R.id.account_channel_recyclerView); + + swipeRefreshLayoutVideos = findViewById(R.id.account_swipeRefreshLayout_videos); + swipeRefreshLayoutChannels = findViewById(R.id.account_swipeRefreshLayout_channels); + aboutView = findViewById(R.id.account_about); + + RecyclerView.LayoutManager layoutManagerVideos = new LinearLayoutManager(AccountActivity.this); + recyclerViewVideos.setLayoutManager(layoutManagerVideos); + + RecyclerView.LayoutManager layoutManagerVideosChannels = new LinearLayoutManager(AccountActivity.this); + recyclerViewChannels.setLayoutManager(layoutManagerVideosChannels); + + videoAdapter = new VideoAdapter(new ArrayList<>(), AccountActivity.this); + recyclerViewVideos.setAdapter(videoAdapter); + + channelAdapter = new ChannelAdapter(new ArrayList<>(), AccountActivity.this); + recyclerViewChannels.setAdapter(channelAdapter); - @Override - public boolean onOptionsItemSelected(MenuItem item) { + swipeRefreshLayoutVideos.setOnRefreshListener(() -> { + // Refresh items + if (!isLoadingVideos) { + videosCurrentStart = 0; + loadAccountVideos(displayNameAndHost); + } + }); - switch (item.getItemId()) { - // action with ID action_refresh was selected + // get video ID + Intent intent = getIntent(); + displayNameAndHost = intent.getStringExtra(VideoListActivity.EXTRA_ACCOUNTDISPLAYNAME); + Log.v(TAG, "click: " + displayNameAndHost); - case R.id.action_logout: - Session.getInstance().invalidate(); - Intent intent = new Intent(this, LoginActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - this.startActivity(intent); - finish(); - return true; - default: - break; - } - return super.onOptionsItemSelected(item); + createBottomBarNavigation(); + + videosStart = 0; + videosCount = 25; + videosCurrentStart = 0; + videosFilter = ""; + videosSort = "-publishedAt"; + videosNsfw = ""; + + + // Attaching the layout to the toolbar object + Toolbar toolbar = findViewById(R.id.tool_bar_account); + // Setting toolbar as the ActionBar with setSupportActionBar() call + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setTitle(displayNameAndHost); + getSupportActionBar().setHomeAsUpIndicator( + new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar() + ); + + loadAccountVideos(displayNameAndHost); + } @Override @@ -100,76 +159,178 @@ public class AccountActivity extends CommonActivity { return false; } - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + private void loadAccount(String ownerString) { - setContentView(R.layout.activity_account); + // get video details from api + Call call = userService.getAccount(ownerString); - // Attaching the layout to the toolbar object - Toolbar toolbar = findViewById(R.id.tool_bar_user); - // Setting toolbar as the ActionBar with setSupportActionBar() call - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeAsUpIndicator( - new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar() - ); - - - init(); - } - - private void init() { - // try to get user data - getUserData(); - } - - private boolean getUserData() { - - // TODO - - - String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); - - GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); - - Call call = service.getMe(); - - call.enqueue(new Callback() { + call.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + Account account = response.body(); - Me me = response.body(); + String owner = MetaDataHelper.getOwnerString(account.getName(), + account.getHost(), + AccountActivity.this + ); - TextView username = findViewById(R.id.account_username); - TextView email = findViewById(R.id.account_email); + // set view data + TextView ownerStringView = findViewById(R.id.account_owner_string); + ownerStringView.setText(owner); - username.setText(me.getUsername()); - email.setText(me.getEmail()); + TextView followers = findViewById(R.id.account_followers); + followers.setText(account.getFollowersCount().toString()); - Log.v(TAG, me.getEmail()); + TextView description = findViewById(R.id.account_description); + description.setText(account.getDescription()); + TextView joined = findViewById(R.id.account_joined); + joined.setText(account.getCreatedAt().toString()); + + + } else { + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); } } @Override - public void onFailure(Call call, Throwable t) { - + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.wtf(TAG, t.fillInStackTrace()); + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); } }); - return true; } - @Override - protected void onResume() { - super.onResume(); - init(); + private void loadAccountVideos(String displayNameAndHost) { + + isLoadingVideos = false; + + GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); + Call call; + + call = service.getAccountVideosData(displayNameAndHost, videosStart, videosCount, videosSort); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + Log.v(TAG, response.toString()); + + if (response.isSuccessful()) { + if (videosCurrentStart == 0) { + videoAdapter.clearData(); + } + + if (response.body() != null) { + videoAdapter.setData(response.body().getVideoArrayList()); + } + + } else{ + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); + + } + + isLoadingVideos = false; + swipeRefreshLayoutVideos.setRefreshing(false); + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.wtf("err", t.fillInStackTrace()); + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); + isLoadingVideos = false; + swipeRefreshLayoutVideos.setRefreshing(false); + } + }); + } + + private void loadAccountChannels(String displayNameAndHost) { + + // get video details from api + Call call = userService.getAccountChannels(displayNameAndHost); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + + if (response.isSuccessful()) { + ChannelList channelList = response.body(); + + + + } else { + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); + } + + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.wtf(TAG, t.fillInStackTrace()); + Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); + } + }); + } + + + + private void createBottomBarNavigation() { + + // Get Bottom Navigation + BottomNavigationView navigation = findViewById(R.id.account_navigation); + + // Always show text label + navigation.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); + + // Add Icon font + Menu navMenu = navigation.getMenu(); + navMenu.findItem(R.id.account_navigation_about).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_user)); + navMenu.findItem(R.id.account_navigation_channels).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_list)); + navMenu.findItem(R.id.account_navigation_videos).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_video)); + + // Click Listener + navigation.setOnNavigationItemSelectedListener(menuItem -> { + switch (menuItem.getItemId()) { + case R.id.account_navigation_about: + + swipeRefreshLayoutVideos.setVisibility(View.GONE); + swipeRefreshLayoutChannels.setVisibility(View.GONE); + aboutView.setVisibility(View.VISIBLE); + loadAccount(displayNameAndHost); + + return true; + case R.id.account_navigation_channels: + + swipeRefreshLayoutVideos.setVisibility(View.GONE); + swipeRefreshLayoutChannels.setVisibility(View.VISIBLE); + aboutView.setVisibility(View.GONE); + loadAccountChannels(displayNameAndHost); + + return true; + case R.id.account_navigation_videos: + + swipeRefreshLayoutVideos.setVisibility(View.VISIBLE); + swipeRefreshLayoutChannels.setVisibility(View.GONE); + aboutView.setVisibility(View.GONE); + loadAccountVideos(displayNameAndHost); + + return true; + + } + return false; + }); } } diff --git a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java index 56fa0e4..d64c339 100644 --- a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java @@ -40,15 +40,11 @@ import net.schueller.peertube.network.AuthenticationService; import net.schueller.peertube.network.RetrofitInstance; import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -import static net.schueller.peertube.helper.Constants.DEFAULT_THEME; -import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY; - public class LoginActivity extends CommonActivity { private String TAG = "LoginActivity"; @@ -148,7 +144,7 @@ public class LoginActivity extends CommonActivity { Log.wtf(TAG, "Logged in"); - Intent intent = new Intent(context, AccountActivity.class); + Intent intent = new Intent(context, MeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(intent); diff --git a/app/src/main/java/net/schueller/peertube/activity/MeActivity.java b/app/src/main/java/net/schueller/peertube/activity/MeActivity.java new file mode 100644 index 0000000..4153d74 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/activity/MeActivity.java @@ -0,0 +1,162 @@ +/* + * 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 android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.TextView; + +import com.mikepenz.fontawesome_typeface_library.FontAwesome; +import com.mikepenz.iconics.IconicsDrawable; + +import net.schueller.peertube.R; +import net.schueller.peertube.helper.APIUrlHelper; +import net.schueller.peertube.model.Me; +import net.schueller.peertube.network.GetUserService; +import net.schueller.peertube.network.RetrofitInstance; +import net.schueller.peertube.network.Session; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class MeActivity extends CommonActivity { + + + private static final String TAG = "MeActivity"; + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_top_account, menu); + + // Set an icon in the ActionBar + menu.findItem(R.id.action_logout).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_sign_out_alt).actionBar()); + + return true; + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + // action with ID action_refresh was selected + + case R.id.action_logout: + Session.getInstance().invalidate(); + Intent intent = new Intent(this, LoginActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + this.startActivity(intent); + finish(); + return true; + default: + break; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onSupportNavigateUp() { + finish(); // close this activity as oppose to navigating up + + return false; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_me); + + // Attaching the layout to the toolbar object + Toolbar toolbar = findViewById(R.id.tool_bar_me); + // Setting toolbar as the ActionBar with setSupportActionBar() call + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeAsUpIndicator( + new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar() + ); + + + init(); + } + + private void init() { + // try to get user data + getUserData(); + } + + private boolean getUserData() { + + // TODO + + + String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); + + GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); + + Call call = service.getMe(); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + if (response.isSuccessful()) { + + Me me = response.body(); + + TextView username = findViewById(R.id.account_username); + TextView email = findViewById(R.id.account_email); + + username.setText(me.getUsername()); + email.setText(me.getEmail()); + + Log.v(TAG, me.getEmail()); + + } + + + } + + @Override + public void onFailure(Call call, Throwable t) { + + } + }); + + return true; + } + + @Override + protected void onResume() { + super.onResume(); + + init(); + + } +} 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 95a0f73..f69700a 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -70,7 +70,8 @@ public class VideoListActivity extends CommonActivity { private String TAG = "VideoListActivity"; - public static final String EXTRA_VIDEOID = "VIDEOID "; + public static final String EXTRA_VIDEOID = "VIDEOID"; + public static final String EXTRA_ACCOUNTDISPLAYNAME = "ACCOUNTDISPLAYNAMEANDHOST"; private VideoAdapter videoAdapter; private SwipeRefreshLayout swipeRefreshLayout; @@ -288,7 +289,7 @@ public class VideoListActivity extends CommonActivity { @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { Log.wtf("err", t.fillInStackTrace()); - Toast.makeText(VideoListActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show(); + Toast.makeText(VideoListActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show(); isLoading = false; swipeRefreshLayout.setRefreshing(false); } @@ -427,7 +428,7 @@ public class VideoListActivity extends CommonActivity { Intent intent = new Intent(this, LoginActivity.class); this.startActivity(intent); } else { - Intent intent = new Intent(this, AccountActivity.class); + Intent intent = new Intent(this, MeActivity.class); this.startActivity(intent); } diff --git a/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java b/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java new file mode 100644 index 0000000..082256b --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java @@ -0,0 +1,175 @@ +/* + * 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.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.mikepenz.iconics.Iconics; +import com.squareup.picasso.Picasso; + +import net.schueller.peertube.R; +import net.schueller.peertube.activity.VideoPlayActivity; +import net.schueller.peertube.helper.APIUrlHelper; +import net.schueller.peertube.helper.MetaDataHelper; +import net.schueller.peertube.intents.Intents; +import net.schueller.peertube.model.Avatar; +import net.schueller.peertube.model.Video; + +import java.util.ArrayList; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.PopupMenu; +import androidx.recyclerview.widget.RecyclerView; + +import static net.schueller.peertube.activity.VideoListActivity.EXTRA_VIDEOID; + +public class ChannelAdapter extends RecyclerView.Adapter { + + + private ArrayList