/*
* Nextcloud Android client application
*
* @author Andy Scherzinger
* Copyright (C) 2018 Andy Scherzinger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see .
*/
package com.owncloud.android.ui.fragment;
import android.accounts.Account;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.activities.GetRemoteActivitiesOperation;
import com.owncloud.android.lib.resources.activities.models.RichObject;
import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.ui.adapter.ActivityListAdapter;
import com.owncloud.android.ui.interfaces.ActivityListInterface;
import com.owncloud.android.utils.ThemeUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindString;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class FileDetailActivitiesFragment extends Fragment implements ActivityListInterface {
private static final String TAG = FileDetailActivitiesFragment.class.getSimpleName();
private static final String ARG_FILE = "FILE";
private static final String ARG_ACCOUNT = "ACCOUNT";
private ActivityListAdapter adapter;
private Unbinder unbinder;
private OwnCloudClient ownCloudClient;
private OCFile file;
private Account account;
private String nextPageUrl;
private boolean isLoadingActivities;
@BindView(R.id.empty_list_view)
public LinearLayout emptyContentContainer;
@BindView(R.id.swipe_containing_list)
public SwipeRefreshLayout swipeListRefreshLayout;
@BindView(R.id.swipe_containing_empty)
public SwipeRefreshLayout swipeEmptyListRefreshLayout;
@BindView(R.id.empty_list_view_text)
public TextView emptyContentMessage;
@BindView(R.id.empty_list_view_headline)
public TextView emptyContentHeadline;
@BindView(R.id.empty_list_icon)
public ImageView emptyContentIcon;
@BindView(R.id.empty_list_progress)
public ProgressBar emptyContentProgressBar;
@BindView(android.R.id.list)
public RecyclerView recyclerView;
@BindString(R.string.activities_no_results_headline)
public String noResultsHeadline;
@BindString(R.string.activities_no_results_message)
public String noResultsMessage;
public static FileDetailActivitiesFragment newInstance(OCFile file, Account account) {
FileDetailActivitiesFragment fragment = new FileDetailActivitiesFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_FILE, file);
args.putParcelable(ARG_ACCOUNT, account);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
file = getArguments().getParcelable(ARG_FILE);
account = getArguments().getParcelable(ARG_ACCOUNT);
if (savedInstanceState != null) {
file = savedInstanceState.getParcelable(FileActivity.EXTRA_FILE);
account = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
}
View view = inflater.inflate(R.layout.file_details_activities_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
setupView();
onCreateSwipeToRefresh(swipeEmptyListRefreshLayout);
onCreateSwipeToRefresh(swipeListRefreshLayout);
fetchAndSetData(null);
swipeListRefreshLayout.setOnRefreshListener(() -> {
setLoadingMessage();
if (swipeListRefreshLayout != null && swipeListRefreshLayout.isRefreshing()) {
swipeListRefreshLayout.setRefreshing(false);
}
fetchAndSetData(null);
}
);
swipeEmptyListRefreshLayout.setOnRefreshListener(() -> {
setLoadingMessage();
if (swipeEmptyListRefreshLayout != null && swipeEmptyListRefreshLayout.isRefreshing()) {
swipeEmptyListRefreshLayout.setRefreshing(false);
}
fetchAndSetData(null);
}
);
return view;
}
private void setLoadingMessage() {
emptyContentHeadline.setText(R.string.file_list_loading);
emptyContentMessage.setText("");
emptyContentIcon.setVisibility(View.GONE);
emptyContentProgressBar.setVisibility(View.VISIBLE);
}
@Override
public void onDestroy() {
super.onDestroy();
unbinder.unbind();
}
private void setupView() {
FileDataStorageManager storageManager = new FileDataStorageManager(account, getActivity().getContentResolver());
emptyContentProgressBar.getIndeterminateDrawable().setColorFilter(ThemeUtils.primaryAccentColor(getContext()),
PorterDuff.Mode.SRC_IN);
emptyContentIcon.setImageDrawable(getResources().getDrawable(R.drawable.ic_activity_light_grey));
adapter = new ActivityListAdapter(getContext(), this, storageManager);
recyclerView.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = recyclerView.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemIndex = layoutManager.findFirstVisibleItemPosition();
// synchronize loading state when item count changes
if (!isLoadingActivities && (totalItemCount - visibleItemCount) <= (firstVisibleItemIndex + 5)
&& nextPageUrl != null && !nextPageUrl.isEmpty()) {
// Almost reached the end, continue to load new activities
fetchAndSetData(nextPageUrl);
}
}
});
}
/**
* @param pageUrl String
*/
private void fetchAndSetData(String pageUrl) {
final Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
final Context context = MainApp.getAppContext();
Thread t = new Thread(() -> {
OwnCloudAccount ocAccount;
try {
ocAccount = new OwnCloudAccount(currentAccount, context);
ownCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton().
getClientFor(ocAccount, MainApp.getAppContext());
ownCloudClient.setOwnCloudVersion(AccountUtils.getServerVersion(currentAccount));
isLoadingActivities = true;
GetRemoteActivitiesOperation getRemoteNotificationOperation = new GetRemoteActivitiesOperation(
file.getLocalId());
if (pageUrl != null) {
getRemoteNotificationOperation.setNextUrl(pageUrl);
}
Log_OC.d(TAG, "BEFORE getRemoteActivitiesOperation.execute");
final RemoteOperationResult result = getRemoteNotificationOperation.execute(ownCloudClient);
if (result.isSuccess() && result.getData() != null) {
final ArrayList