blob: 689f23adb743ac8a101253a72a282ce134818e28 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.sample.githubbrowser.model;
import android.support.annotation.MainThread;
import android.text.TextUtils;
import com.android.sample.githubbrowser.ContributorData;
import com.android.sample.githubbrowser.network.GithubNetworkManager;
import com.android.support.lifecycle.LiveData;
import com.android.support.lifecycle.ViewModel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
* View model for contributor list data.
*/
public class ContributorListModel implements ViewModel {
private String mOwner;
private String mProject;
private LiveData<List<ContributorData>> mRepositoryListLiveData = new LiveData<>();
private AtomicBoolean mHasNoMoreDataToLoad = new AtomicBoolean(false);
private AtomicInteger mLastRequestedPage = new AtomicInteger(0);
private AtomicBoolean mHasRequestPending = new AtomicBoolean(false);
private GithubNetworkManager.Cancelable mCurrentCall;
/**
* Returns true if the current search term is not empty.
*/
public boolean hasSearchTerms() {
return !TextUtils.isEmpty(mOwner) && !TextUtils.isEmpty(mProject);
}
/**
* Sets new search terms.
*/
@MainThread
public void setSearchTerms(String owner, String project) {
mOwner = owner;
mProject = project;
if (mCurrentCall != null) {
mCurrentCall.cancel();
}
mRepositoryListLiveData.setValue(new ArrayList<ContributorData>());
mHasRequestPending.set(false);
mLastRequestedPage.set(0);
fetchNextPage();
}
private void fetchNextPage() {
mHasRequestPending.set(true);
mCurrentCall = GithubNetworkManager.getInstance().getContributors(
mOwner, mProject, mLastRequestedPage.get() + 1,
new GithubNetworkManager.NetworkCallListener<List<ContributorData>>() {
@Override
public void onLoadEmpty(int httpCode) {
}
@Override
public void onLoadSuccess(List<ContributorData> data) {
int newDataCount = data.size();
if (newDataCount == 0) {
mHasNoMoreDataToLoad.set(true);
return;
}
// Create a new list that will contain the previous pages and the new one
int prevDataCount = mRepositoryListLiveData.getValue().size();
ArrayList<ContributorData> newList =
new ArrayList<>(prevDataCount + newDataCount);
newList.addAll(mRepositoryListLiveData.getValue());
newList.addAll(data);
// Set it on our LiveData object - our observer will update the adapter
mRepositoryListLiveData.setValue(newList);
mLastRequestedPage.incrementAndGet();
mHasRequestPending.set(false);
}
@Override
public void onLoadFailure() {
}
});
}
/**
* Fetches the next page of search data if necessary.
*/
@MainThread
public void fetchMoreIfNecessary() {
if (mHasRequestPending.get() || mHasNoMoreDataToLoad.get()) {
// Previous request still processing or no more results
return;
}
fetchNextPage();
}
/**
* Returns the {@LiveData} object that wraps the current list of contributors that matches the
* last set search terms.
*/
public LiveData<List<ContributorData>> getContributorListLiveData() {
return mRepositoryListLiveData;
}
}