implementing advanced pagination

This commit is contained in:
Mariotaku Lee 2017-04-21 17:23:55 +08:00
parent 5734212f4d
commit 2175f0120e
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
120 changed files with 2047 additions and 1298 deletions

View File

@ -23,6 +23,7 @@ import android.support.annotation.Nullable;
import org.mariotaku.microblog.library.MicroBlogException; import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.mastodon.model.Account; import org.mariotaku.microblog.library.mastodon.model.Account;
import org.mariotaku.microblog.library.mastodon.model.AccountUpdate; import org.mariotaku.microblog.library.mastodon.model.AccountUpdate;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.mastodon.model.Relationship; import org.mariotaku.microblog.library.mastodon.model.Relationship;
import org.mariotaku.microblog.library.mastodon.model.Status; import org.mariotaku.microblog.library.mastodon.model.Status;
import org.mariotaku.microblog.library.mastodon.model.TimelineOption; import org.mariotaku.microblog.library.mastodon.model.TimelineOption;
@ -34,8 +35,6 @@ import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Path; import org.mariotaku.restfu.annotation.param.Path;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
@ -52,15 +51,15 @@ public interface AccountResources {
Account updateCredentials(@Param AccountUpdate update) throws MicroBlogException; Account updateCredentials(@Param AccountUpdate update) throws MicroBlogException;
@GET("/v1/accounts/{id}/followers") @GET("/v1/accounts/{id}/followers")
List<Account> getFollowers(@Path("id") String id, @Query Paging paging) LinkHeaderList<Account> getFollowers(@Path("id") String id, @Query Paging paging)
throws MicroBlogException; throws MicroBlogException;
@GET("/v1/accounts/{id}/following") @GET("/v1/accounts/{id}/following")
List<Account> getFollowing(@Path("id") String id, @Query Paging paging) LinkHeaderList<Account> getFollowing(@Path("id") String id, @Query Paging paging)
throws MicroBlogException; throws MicroBlogException;
@GET("/v1/accounts/{id}/statuses") @GET("/v1/accounts/{id}/statuses")
List<Status> getStatuses(@Path("id") String id, @Query Paging paging, LinkHeaderList<Status> getStatuses(@Path("id") String id, @Query Paging paging,
@Query TimelineOption option) throws MicroBlogException; @Query TimelineOption option) throws MicroBlogException;
@POST("/v1/accounts/{id}/follow") @POST("/v1/accounts/{id}/follow")
@ -82,8 +81,8 @@ public interface AccountResources {
Relationship unmuteUser(@Path("id") String id) throws MicroBlogException; Relationship unmuteUser(@Path("id") String id) throws MicroBlogException;
@GET("/v1/accounts/relationships") @GET("/v1/accounts/relationships")
List<Relationship> getRelationships(@Path("id") String id) throws MicroBlogException; LinkHeaderList<Relationship> getRelationships(@Path("id") String id) throws MicroBlogException;
@GET("/v1/accounts/search") @GET("/v1/accounts/search")
List<Account> searchAccounts(@Query("q") String query, @Nullable @Query Paging paging) throws MicroBlogException; LinkHeaderList<Account> searchAccounts(@Query("q") String query, @Nullable @Query Paging paging) throws MicroBlogException;
} }

View File

@ -19,17 +19,16 @@
package org.mariotaku.microblog.library.mastodon.api; package org.mariotaku.microblog.library.mastodon.api;
import org.mariotaku.microblog.library.mastodon.model.Account; import org.mariotaku.microblog.library.mastodon.model.Account;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
public interface BlockResources { public interface BlockResources {
@GET("/v1/blocks") @GET("/v1/blocks")
List<Account> getBlocks(@Query Paging paging); LinkHeaderList<Account> getBlocks(@Query Paging paging);
} }

View File

@ -19,13 +19,12 @@
package org.mariotaku.microblog.library.mastodon.api; package org.mariotaku.microblog.library.mastodon.api;
import org.mariotaku.microblog.library.MicroBlogException; import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.mastodon.model.Status; import org.mariotaku.microblog.library.mastodon.model.Status;
import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
@ -36,6 +35,6 @@ public interface FavouriteResources {
* @return An array of {@link Status} favourited by the authenticated user. * @return An array of {@link Status} favourited by the authenticated user.
*/ */
@GET("/v1/favourites") @GET("/v1/favourites")
List<Status> getFavourites(@Query Paging paging) throws MicroBlogException; LinkHeaderList<Status> getFavourites(@Query Paging paging) throws MicroBlogException;
} }

View File

@ -19,16 +19,15 @@
package org.mariotaku.microblog.library.mastodon.api; package org.mariotaku.microblog.library.mastodon.api;
import org.mariotaku.microblog.library.mastodon.model.Account; import org.mariotaku.microblog.library.mastodon.model.Account;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
public interface FollowRequestResources { public interface FollowRequestResources {
@GET("/v1/follow_requests") @GET("/v1/follow_requests")
List<Account> getFollowRequests(@Query Paging paging); LinkHeaderList<Account> getFollowRequests(@Query Paging paging);
} }

View File

@ -19,17 +19,16 @@
package org.mariotaku.microblog.library.mastodon.api; package org.mariotaku.microblog.library.mastodon.api;
import org.mariotaku.microblog.library.mastodon.model.Account; import org.mariotaku.microblog.library.mastodon.model.Account;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
public interface MuteResources { public interface MuteResources {
@GET("/v1/mutes") @GET("/v1/mutes")
List<Account> getMutes(@Query Paging paging); LinkHeaderList<Account> getMutes(@Query Paging paging);
} }

View File

@ -22,6 +22,7 @@ import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.mastodon.model.Account; import org.mariotaku.microblog.library.mastodon.model.Account;
import org.mariotaku.microblog.library.mastodon.model.Card; import org.mariotaku.microblog.library.mastodon.model.Card;
import org.mariotaku.microblog.library.mastodon.model.Context; import org.mariotaku.microblog.library.mastodon.model.Context;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.mastodon.model.Status; import org.mariotaku.microblog.library.mastodon.model.Status;
import org.mariotaku.microblog.library.mastodon.model.StatusUpdate; import org.mariotaku.microblog.library.mastodon.model.StatusUpdate;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
@ -29,8 +30,6 @@ import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.Param; import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Path; import org.mariotaku.restfu.annotation.param.Path;
import java.util.List;
/** /**
* Created by mariotaku on 2017/4/17. * Created by mariotaku on 2017/4/17.
*/ */
@ -46,10 +45,10 @@ public interface StatusResources {
Card getStatusCard(@Path("id") String id) throws MicroBlogException; Card getStatusCard(@Path("id") String id) throws MicroBlogException;
@GET("/v1/statuses/{id}/reblogged_by") @GET("/v1/statuses/{id}/reblogged_by")
List<Account> getStatusRebloggedBy(@Path("id") String id) throws MicroBlogException; LinkHeaderList<Account> getStatusRebloggedBy(@Path("id") String id) throws MicroBlogException;
@GET("/v1/statuses/{id}/favourited_by") @GET("/v1/statuses/{id}/favourited_by")
List<Account> getStatusFavouritedBy(@Path("id") String id) throws MicroBlogException; LinkHeaderList<Account> getStatusFavouritedBy(@Path("id") String id) throws MicroBlogException;
@POST("/v1/statuses") @POST("/v1/statuses")
Status postStatus(@Param StatusUpdate update) throws MicroBlogException; Status postStatus(@Param StatusUpdate update) throws MicroBlogException;

View File

@ -0,0 +1,68 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 org.mariotaku.microblog.library.mastodon.model;
import com.bluelinelabs.logansquare.JsonMapper;
import com.bluelinelabs.logansquare.LoganSquare;
import com.bluelinelabs.logansquare.ParameterizedType;
import com.bluelinelabs.logansquare.util.SimpleArrayMap;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.mariotaku.microblog.library.annotation.NoObfuscate;
import java.io.IOException;
@SuppressWarnings("unused")
@NoObfuscate
public final class LinkHeaderList$$JsonObjectMapper<T> extends JsonMapper<LinkHeaderList<T>> {
private final JsonMapper<T> m69ClassJsonMapper;
public LinkHeaderList$$JsonObjectMapper(ParameterizedType type, ParameterizedType TType, SimpleArrayMap<ParameterizedType, JsonMapper> partialMappers) {
partialMappers.put(type, this);
//noinspection unchecked
m69ClassJsonMapper = LoganSquare.mapperFor(TType, partialMappers);
}
@Override
public LinkHeaderList<T> parse(JsonParser jsonParser) throws IOException {
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}
LinkHeaderList<T> instance = new LinkHeaderList<>();
final JsonToken currentToken = jsonParser.getCurrentToken();
if (currentToken == JsonToken.START_ARRAY) {
instance.addAll(m69ClassJsonMapper.parseList(jsonParser));
} else {
jsonParser.skipChildren();
}
return instance;
}
@Override
public void parseField(LinkHeaderList<T> instance, String fieldName, JsonParser jsonParser) throws IOException {
}
@Override
public void serialize(LinkHeaderList<T> object, JsonGenerator jsonGenerator, boolean writeStartAndEnd) throws IOException {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,80 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 org.mariotaku.microblog.library.mastodon.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import org.mariotaku.restfu.http.HttpResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Created by mariotaku on 2017/4/21.
*/
public class LinkHeaderList<E> extends ArrayList<E> {
@NonNull
private Map<String, String> linkParts = new HashMap<>();
public LinkHeaderList(int initialCapacity) {
super(initialCapacity);
}
public LinkHeaderList() {
}
public LinkHeaderList(@NonNull Collection<? extends E> c) {
super(c);
}
public final void processResponseHeader(HttpResponse resp) {
linkParts.clear();
String linkHeader = resp.getHeader("Link");
if (linkHeader == null) return;
for (String link : TextUtils.split(linkHeader, ",")) {
String[] segments = TextUtils.split(link, ";");
if (segments.length < 2) continue;
String linkPart = segments[0].trim();
if (!linkPart.startsWith("<") || !linkPart.endsWith(">"))
continue;
linkPart = linkPart.substring(1, linkPart.length() - 1);
for (int i = 1; i < segments.length; i++) {
String[] rel = TextUtils.split(segments[i].trim(), "=");
if (rel.length < 2 || !"rel".equals(rel[0]))
continue;
String relValue = rel[1];
if (relValue.startsWith("\"") && relValue.endsWith("\""))
relValue = relValue.substring(1, relValue.length() - 1);
linkParts.put(relValue, linkPart);
}
}
}
@Nullable
public String getLinkPart(String key) {
return linkParts.get(key);
}
}

View File

@ -18,6 +18,7 @@
package org.mariotaku.microblog.library.statusnet; package org.mariotaku.microblog.library.statusnet;
import org.mariotaku.microblog.library.statusnet.api.TimelineResources;
import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query; import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.microblog.library.statusnet.api.GroupResources; import org.mariotaku.microblog.library.statusnet.api.GroupResources;
@ -30,7 +31,8 @@ import org.mariotaku.microblog.library.twitter.model.User;
/** /**
* Created by mariotaku on 16/3/4. * Created by mariotaku on 16/3/4.
*/ */
public interface StatusNet extends StatusNetResources, GroupResources, SearchResources, UserResources { public interface StatusNet extends StatusNetResources, GroupResources, SearchResources,
UserResources, TimelineResources {
@GET("/externalprofile/show.json") @GET("/externalprofile/show.json")
User showExternalProfile(@Query("profileurl") String profileUrl) throws MicroBlogException; User showExternalProfile(@Query("profileurl") String profileUrl) throws MicroBlogException;

View File

@ -0,0 +1,36 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 org.mariotaku.microblog.library.statusnet.api;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.Status;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query;
/**
* Created by mariotaku on 2017/4/21.
*/
public interface TimelineResources {
@GET("/statuses/networkpublic_timeline.json")
ResponseList<Status> getNetworkPublicTimeline(@Query Paging paging) throws MicroBlogException;
}

View File

@ -23,6 +23,8 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.JsonToken;
import org.mariotaku.microblog.library.annotation.NoObfuscate;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,6 +34,7 @@ import java.util.List;
* Created by mariotaku on 15/10/21. * Created by mariotaku on 15/10/21.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@NoObfuscate
public class IDs$$JsonObjectMapper extends JsonMapper<IDs> { public class IDs$$JsonObjectMapper extends JsonMapper<IDs> {
@SuppressWarnings("TryWithIdenticalCatches") @SuppressWarnings("TryWithIdenticalCatches")

View File

@ -26,9 +26,12 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.JsonToken;
import org.mariotaku.microblog.library.annotation.NoObfuscate;
import java.io.IOException; import java.io.IOException;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@NoObfuscate
public final class PageableResponseList$$JsonObjectMapper<T> extends JsonMapper<PageableResponseList<T>> { public final class PageableResponseList$$JsonObjectMapper<T> extends JsonMapper<PageableResponseList<T>> {
private final JsonMapper<T> m84ClassJsonMapper; private final JsonMapper<T> m84ClassJsonMapper;

View File

@ -45,10 +45,6 @@ public class Paging extends SimpleValueMap {
put("count", count); put("count", count);
} }
public void setPage(int page) {
put("page", page);
}
public void setCursor(long cursor) { public void setCursor(long cursor) {
put("cursor", cursor); put("cursor", cursor);
} }
@ -61,10 +57,6 @@ public class Paging extends SimpleValueMap {
put("latest_results", latestResults); put("latest_results", latestResults);
} }
public void setRpp(int rpp) {
put("rpp", rpp);
}
public Paging sinceId(String sinceId) { public Paging sinceId(String sinceId) {
setSinceId(sinceId); setSinceId(sinceId);
return this; return this;
@ -96,7 +88,7 @@ public class Paging extends SimpleValueMap {
} }
public Paging page(int page) { public Paging page(int page) {
setPage(page); put("page", page);
return this; return this;
} }
@ -110,8 +102,13 @@ public class Paging extends SimpleValueMap {
return this; return this;
} }
public Paging limit(int limit) {
put("limit", limit);
return this;
}
public Paging rpp(int rpp) { public Paging rpp(int rpp) {
setRpp(rpp); put("rpp", rpp);
return this; return this;
} }
} }

View File

@ -18,9 +18,11 @@
package org.mariotaku.microblog.library.twitter.model; package org.mariotaku.microblog.library.twitter.model;
import android.support.annotation.NonNull;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.restfu.RestConverter; import org.mariotaku.restfu.RestConverter;
import org.mariotaku.restfu.http.HttpResponse; import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.microblog.library.MicroBlogException;
/** /**
* Created by mariotaku on 15/6/15. * Created by mariotaku on 15/6/15.
@ -43,8 +45,9 @@ public class ResponseCode {
public static class ResponseConverter implements RestConverter<HttpResponse, ResponseCode, MicroBlogException> { public static class ResponseConverter implements RestConverter<HttpResponse, ResponseCode, MicroBlogException> {
@NonNull
@Override @Override
public ResponseCode convert(HttpResponse response) { public ResponseCode convert(@NonNull HttpResponse response) {
return new ResponseCode(response); return new ResponseCode(response);
} }
} }

View File

@ -18,11 +18,10 @@
package org.mariotaku.microblog.library.twitter.model; package org.mariotaku.microblog.library.twitter.model;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.microblog.library.annotation.NoObfuscate; import org.mariotaku.microblog.library.annotation.NoObfuscate;
import org.mariotaku.microblog.library.twitter.util.InternalParseUtil; import org.mariotaku.microblog.library.twitter.util.InternalParseUtil;
import org.mariotaku.restfu.http.HttpResponse;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -31,48 +30,16 @@ import java.util.List;
* Created by mariotaku on 15/5/7. * Created by mariotaku on 15/5/7.
*/ */
@NoObfuscate @NoObfuscate
public class ResponseList<T> extends AbstractList<T> implements TwitterResponse { public class ResponseList<T> extends ArrayList<T> implements TwitterResponse {
private List<T> list;
private int accessLevel; private int accessLevel;
private RateLimitStatus rateLimitStatus; private RateLimitStatus rateLimitStatus;
public ResponseList(List<T> list) { public ResponseList(List<T> list) {
this.list = list; super(list);
}
@Override
public void add(int location, T object) {
list.add(location, object);
}
@Override
public T set(int location, T object) {
return list.set(location, object);
}
@Override
public T get(int location) {
return list.get(location);
}
@Override
public T remove(int location) {
return list.remove(location);
}
@Override
public void clear() {
list.clear();
}
@Override
public int size() {
return list.size();
} }
public ResponseList() { public ResponseList() {
this(new ArrayList<T>());
} }
@Override @Override

View File

@ -18,6 +18,8 @@
package org.mariotaku.microblog.library.twitter.util; package org.mariotaku.microblog.library.twitter.util;
import android.support.annotation.NonNull;
import org.mariotaku.microblog.library.MicroBlogException; import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.restfu.RestConverter; import org.mariotaku.restfu.RestConverter;
import org.mariotaku.restfu.RestFuUtils; import org.mariotaku.restfu.RestFuUtils;
@ -35,8 +37,9 @@ import java.text.ParseException;
* Created by mariotaku on 16/5/21. * Created by mariotaku on 16/5/21.
*/ */
public class OAuthTokenResponseConverter implements RestConverter<HttpResponse, OAuthToken, MicroBlogException> { public class OAuthTokenResponseConverter implements RestConverter<HttpResponse, OAuthToken, MicroBlogException> {
@NonNull
@Override @Override
public OAuthToken convert(HttpResponse response) throws IOException, ConvertException { public OAuthToken convert(@NonNull HttpResponse response) throws IOException, ConvertException {
final Body body = response.getBody(); final Body body = response.getBody();
try { try {
final ContentType contentType = body.contentType(); final ContentType contentType = body.contentType();

View File

@ -161,6 +161,9 @@ public interface IntentConstants {
String EXTRA_URL = "url"; String EXTRA_URL = "url";
String EXTRA_PROFILE_URL = "profile_url"; String EXTRA_PROFILE_URL = "profile_url";
String EXTRA_NEXT_PAGE = "next_page"; String EXTRA_NEXT_PAGE = "next_page";
String EXTRA_NEXT_PAGINATION = "next_pagination";
String EXTRA_PREV_PAGINATION = "prev_pagination";
String EXTRA_PAGINATION = "pagination";
String EXTRA_NEXT_CURSOR = "next_cursor"; String EXTRA_NEXT_CURSOR = "next_cursor";
String EXTRA_PREV_CURSOR = "prev_cursor"; String EXTRA_PREV_CURSOR = "prev_cursor";
String EXTRA_EXTRA_INTENT = "extra_intent"; String EXTRA_EXTRA_INTENT = "extra_intent";

View File

@ -28,8 +28,10 @@ import android.support.annotation.NonNull;
public class IDsAccessor { public class IDsAccessor {
public static void setIds(@NonNull final IDs ids, @NonNull final String[] array) { @NonNull
public static IDs setIds(@NonNull final IDs ids, @NonNull final String[] array) {
ids.ids = array; ids.ids = array;
return ids;
} }
} }

View File

@ -0,0 +1,79 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import android.os.Parcel;
import android.os.Parcelable;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import org.jetbrains.annotations.Nullable;
import org.mariotaku.microblog.library.twitter.model.Paging;
/**
* Created by mariotaku on 2017/4/21.
*/
@ParcelablePlease
public class CursorPagination implements Pagination, Parcelable {
String cursor;
CursorPagination() {
}
public String getCursor() {
return cursor;
}
@Override
public void applyTo(Paging paging) {
paging.cursor(cursor);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
CursorPaginationParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<CursorPagination> CREATOR = new Creator<CursorPagination>() {
public CursorPagination createFromParcel(Parcel source) {
CursorPagination target = new CursorPagination();
CursorPaginationParcelablePlease.readFromParcel(target, source);
return target;
}
public CursorPagination[] newArray(int size) {
return new CursorPagination[size];
}
};
@Nullable
public static CursorPagination valueOf(long cursor) {
if (cursor == 0) return null;
final CursorPagination pagination = new CursorPagination();
pagination.cursor = String.valueOf(cursor);
return pagination;
}
}

View File

@ -0,0 +1,80 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import android.os.Parcel;
import android.os.Parcelable;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import org.jetbrains.annotations.Nullable;
import org.mariotaku.microblog.library.twitter.model.Paging;
/**
* Created by mariotaku on 2017/4/21.
*/
@ParcelablePlease
public class PagePagination implements Pagination, Parcelable {
int page;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
@Override
public void applyTo(Paging paging) {
paging.page(page);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
PagePaginationParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<PagePagination> CREATOR = new Creator<PagePagination>() {
public PagePagination createFromParcel(Parcel source) {
PagePagination target = new PagePagination();
PagePaginationParcelablePlease.readFromParcel(target, source);
return target;
}
public PagePagination[] newArray(int size) {
return new PagePagination[size];
}
};
@Nullable
public static PagePagination valueOf(int page) {
if (page <= 0) return null;
final PagePagination pagination = new PagePagination();
pagination.page = page;
return pagination;
}
}

View File

@ -0,0 +1,64 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Collection;
/**
* Created by mariotaku on 2017/4/21.
*/
public class PaginatedArrayList<E> extends ArrayList<E> implements PaginatedList<E> {
private Pagination previousPage;
private Pagination nextPage;
public PaginatedArrayList(int initialCapacity) {
super(initialCapacity);
}
public PaginatedArrayList() {
}
public PaginatedArrayList(@NonNull Collection<? extends E> c) {
super(c);
}
@Override
public Pagination getPreviousPage() {
return previousPage;
}
@Override
public Pagination getNextPage() {
return nextPage;
}
public void setPreviousPage(Pagination previousPage) {
this.previousPage = previousPage;
}
public void setNextPage(Pagination nextPage) {
this.nextPage = nextPage;
}
}

View File

@ -0,0 +1,34 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import java.util.List;
/**
* Created by mariotaku on 2017/4/21.
*/
public interface PaginatedList<E> extends List<E> {
Pagination getPreviousPage();
Pagination getNextPage();
}

View File

@ -0,0 +1,34 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import android.os.Parcelable;
import org.mariotaku.microblog.library.twitter.model.Paging;
/**
* Created by mariotaku on 2017/4/21.
*/
public interface Pagination extends Parcelable {
void applyTo(Paging paging);
}

View File

@ -0,0 +1,86 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.pagination;
import android.os.Parcel;
import android.os.Parcelable;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import org.mariotaku.microblog.library.twitter.model.Paging;
/**
* Created by mariotaku on 2017/4/21.
*/
@ParcelablePlease
public class SinceMaxPagination implements Pagination, Parcelable {
String sinceId;
String maxId;
public String getSinceId() {
return sinceId;
}
public void setSinceId(String sinceId) {
this.sinceId = sinceId;
}
public String getMaxId() {
return maxId;
}
public void setMaxId(String maxId) {
this.maxId = maxId;
}
@Override
public void applyTo(Paging paging) {
if (sinceId != null) {
paging.sinceId(sinceId);
}
if (maxId != null) {
paging.maxId(maxId);
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
SinceMaxPaginationParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<SinceMaxPagination> CREATOR = new Creator<SinceMaxPagination>() {
public SinceMaxPagination createFromParcel(Parcel source) {
SinceMaxPagination target = new SinceMaxPagination();
SinceMaxPaginationParcelablePlease.readFromParcel(target, source);
return target;
}
public SinceMaxPagination[] newArray(int size) {
return new SinceMaxPagination[size];
}
};
}

View File

@ -62,6 +62,7 @@ import org.mariotaku.twidere.fragment.message.MessageConversationInfoFragment
import org.mariotaku.twidere.fragment.message.MessageNewConversationFragment import org.mariotaku.twidere.fragment.message.MessageNewConversationFragment
import org.mariotaku.twidere.fragment.message.MessagesConversationFragment import org.mariotaku.twidere.fragment.message.MessagesConversationFragment
import org.mariotaku.twidere.fragment.message.MessagesEntriesFragment import org.mariotaku.twidere.fragment.message.MessagesEntriesFragment
import org.mariotaku.twidere.fragment.users.*
import org.mariotaku.twidere.graphic.EmptyDrawable import org.mariotaku.twidere.graphic.EmptyDrawable
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.analyzer.PurchaseFinished import org.mariotaku.twidere.model.analyzer.PurchaseFinished
@ -521,7 +522,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
@Throws(Utils.NoAccountException::class) @Throws(Utils.NoAccountException::class)
private fun createFragmentForIntent(context: Context, linkId: Int, intent: Intent): Fragment? { private fun createFragmentForIntent(context: Context, linkId: Int, intent: Intent): Fragment? {
intent.setExtrasClassLoader(context.classLoader) intent.setExtrasClassLoader(classLoader)
val extras = intent.extras val extras = intent.extras
val uri = intent.data val uri = intent.data
val fragment: Fragment val fragment: Fragment

View File

@ -39,11 +39,12 @@ import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserListOwnershipsLoader import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.loader.iface.ICursorSupportLoader import org.mariotaku.twidere.loader.userlists.UserListOwnershipsLoader
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.util.ContentScrollHandler import org.mariotaku.twidere.util.ContentScrollHandler
import org.mariotaku.twidere.util.ListViewScrollHandler import org.mariotaku.twidere.util.ListViewScrollHandler
@ -53,13 +54,26 @@ class UserListSelectorActivity : BaseActivity(),
override lateinit var adapter: SimpleParcelableUserListsAdapter override lateinit var adapter: SimpleParcelableUserListsAdapter
override var refreshing: Boolean
get() {
return supportLoaderManager.hasRunningLoadersSafe()
}
set(value) {
}
override val reachingStart: Boolean
get() = listView.firstVisiblePosition <= 0
override val reachingEnd: Boolean
get() = listView.lastVisiblePosition >= listView.count - 1
private val accountKey: UserKey? private val accountKey: UserKey?
get() = intent.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY) get() = intent.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
private val showMyLists: Boolean private val showMyLists: Boolean
get() = intent.getBooleanExtra(EXTRA_SHOW_MY_LISTS, false) get() = intent.getBooleanExtra(EXTRA_SHOW_MY_LISTS, false)
private var userKey: UserKey? = null private var userKey: UserKey? = null
private var nextCursor: Long = -1 private var nextPagination: Pagination? = null
private var loaderInitialized: Boolean = false private var loaderInitialized: Boolean = false
@ -135,7 +149,7 @@ class UserListSelectorActivity : BaseActivity(),
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
val nextCursor = args.getLong(EXTRA_NEXT_CURSOR) val nextCursor = args.getLong(EXTRA_NEXT_CURSOR)
return UserListOwnershipsLoader(this, accountKey, userKey, null, nextCursor, adapter.all) return UserListOwnershipsLoader(this, accountKey, userKey, null, adapter.all)
} }
override fun onLoaderReset(loader: Loader<List<ParcelableUserList>>?) { override fun onLoaderReset(loader: Loader<List<ParcelableUserList>>?) {
@ -152,8 +166,8 @@ class UserListSelectorActivity : BaseActivity(),
} }
adapter.setData(data) adapter.setData(data)
refreshing = false refreshing = false
if (loader is ICursorSupportLoader) { if (loader is IPaginationLoader) {
nextCursor = loader.nextCursor nextPagination = loader.nextPagination
} }
showList() showList()
} }
@ -161,18 +175,6 @@ class UserListSelectorActivity : BaseActivity(),
override fun setControlVisible(visible: Boolean) { override fun setControlVisible(visible: Boolean) {
} }
override var refreshing: Boolean
get() {
return supportLoaderManager.hasRunningLoadersSafe()
}
set(value) {
}
override val reachingStart: Boolean
get() = listView.firstVisiblePosition <= 0
override val reachingEnd: Boolean
get() = listView.lastVisiblePosition >= listView.count - 1
override fun onLoadMoreContents(@IndicatorPosition position: Long) { override fun onLoadMoreContents(@IndicatorPosition position: Long) {
val accountKey = this.accountKey ?: return val accountKey = this.accountKey ?: return
@ -181,10 +183,10 @@ class UserListSelectorActivity : BaseActivity(),
return return
} }
adapter.loadMoreIndicatorPosition = position adapter.loadMoreIndicatorPosition = position
loadUserLists(accountKey, userKey, nextCursor) loadUserLists(accountKey, userKey, nextPagination)
} }
private fun loadUserLists(accountKey: UserKey, userKey: UserKey, nextCursor: Long = -1) { private fun loadUserLists(accountKey: UserKey, userKey: UserKey, pagination: Pagination? = null) {
if (userKey != this.userKey) { if (userKey != this.userKey) {
adapter.clear() adapter.clear()
showProgress() showProgress()
@ -193,7 +195,7 @@ class UserListSelectorActivity : BaseActivity(),
val args = Bundle { val args = Bundle {
this[EXTRA_ACCOUNT_KEY] = accountKey this[EXTRA_ACCOUNT_KEY] = accountKey
this[EXTRA_USER_KEY] = userKey this[EXTRA_USER_KEY] = userKey
this[EXTRA_NEXT_CURSOR] = nextCursor this[EXTRA_PAGINATION] = pagination
} }
if (!loaderInitialized) { if (!loaderInitialized) {
loaderInitialized = true loaderInitialized = true

View File

@ -37,6 +37,7 @@ import org.mariotaku.ktextension.isNotNullOrEmpty
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CacheUserSearchLoader import org.mariotaku.twidere.loader.CacheUserSearchLoader
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
@ -100,7 +101,7 @@ class UserSelectorActivity : BaseActivity(), OnItemClickListener, LoaderManager.
val list = view as ListView val list = view as ListView
val user = adapter.getItem(position - list.headerViewsCount) ?: return val user = adapter.getItem(position - list.headerViewsCount) ?: return
val data = Intent() val data = Intent()
data.setExtrasClassLoader(classLoader) data.setExtrasClassLoader(TwidereApplication::class.java.classLoader)
data.putExtra(EXTRA_USER, user) data.putExtra(EXTRA_USER, user)
data.putExtra(EXTRA_EXTRAS, intent.getBundleExtra(EXTRA_EXTRAS)) data.putExtra(EXTRA_EXTRAS, intent.getBundleExtra(EXTRA_EXTRAS))
setResult(Activity.RESULT_OK, data) setResult(Activity.RESULT_OK, data)

View File

@ -0,0 +1,24 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.exception
import org.mariotaku.microblog.library.MicroBlogException
class APINotSupportedException(platform: String = "this platform") : MicroBlogException("API not supported for $platform")

View File

@ -21,17 +21,39 @@ package org.mariotaku.twidere.extension.api
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.IDs
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.model.pagination.CursorPagination
/** import org.mariotaku.twidere.model.pagination.PaginatedArrayList
* Created by mariotaku on 2017/4/20. import org.mariotaku.twidere.model.pagination.PaginatedList
*/
@Throws(MicroBlogException::class) @Throws(MicroBlogException::class)
fun MicroBlog.showUser(id: String?, screenName: String?, accountType: String?): User { fun MicroBlog.tryShowUser(id: String?, screenName: String?, accountType: String?): User {
try {
return showUser(id, screenName, accountType)
} catch (e: MicroBlogException) {
// Twitter specific error for private API calling through proxy
if (e.statusCode == 200) {
return showUserAlternative(id, screenName)
}
throw e
}
}
@Throws(MicroBlogException::class)
inline fun <R> MicroBlog.lookupUsersMapPaginated(ids: IDs, transform: (User) -> R): PaginatedList<R> {
val response = lookupUsers(ids.iDs)
val result = response.mapTo(PaginatedArrayList(response.size), transform)
result.previousPage = CursorPagination.valueOf(ids.previousCursor)
result.nextPage = CursorPagination.valueOf(ids.nextCursor)
return result
}
@Throws(MicroBlogException::class)
private fun MicroBlog.showUser(id: String?, screenName: String?, accountType: String?): User {
if (id != null) { if (id != null) {
if (AccountType.FANFOU == accountType) { if (AccountType.FANFOU == accountType) {
return showFanfouUser(id) return showFanfouUser(id)
@ -47,7 +69,7 @@ fun MicroBlog.showUser(id: String?, screenName: String?, accountType: String?):
} }
@Throws(MicroBlogException::class) @Throws(MicroBlogException::class)
fun MicroBlog.showUserAlternative(id: String?, screenName: String?): User { private fun MicroBlog.showUserAlternative(id: String?, screenName: String?): User {
val searchScreenName: String = screenName ?: run { val searchScreenName: String = screenName ?: run {
if (id == null) throw IllegalArgumentException() if (id == null) throw IllegalArgumentException()
return@run showFriendship(id).targetUserScreenName return@run showFriendship(id).targetUserScreenName
@ -68,17 +90,3 @@ fun MicroBlog.showUserAlternative(id: String?, screenName: String?): User {
throw MicroBlogException("Can't find user") throw MicroBlogException("Can't find user")
} }
@Throws(MicroBlogException::class)
fun MicroBlog.tryShowUser(id: String?, screenName: String?, accountType: String?): User {
try {
return showUser(id, screenName, accountType)
} catch (e: MicroBlogException) {
// Twitter specific error for private API calling through proxy
if (e.statusCode == 200) {
return showUserAlternative(id, screenName)
}
throw e
}
}

View File

@ -0,0 +1,51 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension.model.api.mastodon
import android.net.Uri
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList
import org.mariotaku.twidere.model.pagination.PaginatedArrayList
import org.mariotaku.twidere.model.pagination.PaginatedList
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
/**
* Created by mariotaku on 2017/4/21.
*/
inline fun <T, R> LinkHeaderList<T>.mapToPaginated(transform: (T) -> R): PaginatedList<R> {
val result = mapTo(PaginatedArrayList(size), transform)
result.previousPage = getLinkPagination("prev")
result.nextPage = getLinkPagination("next")
return result
}
fun LinkHeaderList<*>.getLinkPagination(key: String): Pagination? {
val uri = getLinkPart(key)?.let(Uri::parse) ?: return null
val maxId = uri.getQueryParameter("max_id")
val sinceId = uri.getQueryParameter("since_id")
if (maxId != null || sinceId != null) {
return SinceMaxPagination().apply {
this.maxId = maxId
this.sinceId = sinceId
}
}
return null
}

View File

@ -0,0 +1,48 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension.model.api.microblog
import org.mariotaku.microblog.library.twitter.model.PageableResponseList
import org.mariotaku.microblog.library.twitter.model.ResponseList
import org.mariotaku.twidere.model.pagination.*
/**
* Created by mariotaku on 2017/4/21.
*/
inline fun <T, R> ResponseList<T>.mapToPaginated(current: Pagination?, transform: (T) -> R): PaginatedList<R> {
val result = mapTo(PaginatedArrayList(size), transform)
if (current == null) {
// Assume we are on page 1
result.previousPage = null
result.nextPage = PagePagination.valueOf(2)
} else if (current is PagePagination) {
result.previousPage = PagePagination.valueOf(current.page - 1)
result.nextPage = PagePagination.valueOf(current.page + 1)
}
return result
}
inline fun <T, R> PageableResponseList<T>.mapToPaginated(transform: (T) -> R): PaginatedList<R> {
val result = mapTo(PaginatedArrayList(size), transform)
result.previousPage = CursorPagination.valueOf(previousCursor)
result.nextPage = CursorPagination.valueOf(nextCursor)
return result
}

View File

@ -517,7 +517,7 @@ abstract class AbsActivitiesFragment protected constructor() :
} }
override fun createItemDecoration(context: Context, recyclerView: RecyclerView, override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? { layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
val itemDecoration = object : ExtendedDividerItemDecoration(context, val itemDecoration = object : ExtendedDividerItemDecoration(context,
(recyclerView.layoutManager as LinearLayoutManager).orientation) { (recyclerView.layoutManager as LinearLayoutManager).orientation) {

View File

@ -37,7 +37,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
abstract class AbsContentListRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>> abstract class AbsContentListRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>>
: AbsContentRecyclerViewFragment<A, LinearLayoutManager>() { : AbsContentRecyclerViewFragment<A, LinearLayoutManager>() {
override fun createItemDecoration(context: Context, recyclerView: RecyclerView, override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? { layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
return ExtendedDividerItemDecoration(context, layoutManager.orientation) return ExtendedDividerItemDecoration(context, layoutManager.orientation)
} }

View File

@ -219,7 +219,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
} }
protected open fun setupRecyclerView(context: Context, recyclerView: RecyclerView) { protected open fun setupRecyclerView(context: Context, recyclerView: RecyclerView) {
itemDecoration = createItemDecoration(context, recyclerView, layoutManager) itemDecoration = onCreateItemDecoration(context, recyclerView, layoutManager)
if (itemDecoration != null) { if (itemDecoration != null) {
recyclerView.addItemDecoration(itemDecoration) recyclerView.addItemDecoration(itemDecoration)
} }
@ -270,7 +270,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
protected abstract fun onCreateAdapter(context: Context): A protected abstract fun onCreateAdapter(context: Context): A
protected open fun createItemDecoration(context: Context, recyclerView: RecyclerView, protected open fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: L): ItemDecoration? { layoutManager: L): ItemDecoration? {
return null return null
} }

View File

@ -31,7 +31,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.extension.reachingEnd import org.mariotaku.twidere.extension.reachingEnd
import org.mariotaku.twidere.extension.reachingStart import org.mariotaku.twidere.extension.reachingStart
import org.mariotaku.twidere.loader.AbsRequestStatusesLoader import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.util.IntentUtils

View File

@ -382,7 +382,7 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
return handleActionLongClick(this, status, adapter.getItemId(position), id) return handleActionLongClick(this, status, adapter.getItemId(position), id)
} }
override fun createItemDecoration(context: Context, recyclerView: RecyclerView, layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? { override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView, layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
val itemDecoration = ExtendedDividerItemDecoration(context, (recyclerView.layoutManager as LinearLayoutManager).orientation) val itemDecoration = ExtendedDividerItemDecoration(context, (recyclerView.layoutManager as LinearLayoutManager).orientation)
val res = context.resources val res = context.resources
if (adapter.profileImageEnabled) { if (adapter.profileImageEnabled) {

View File

@ -1,82 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment
import android.content.Context
import android.os.Bundle
import android.support.v4.content.Loader
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.model.ParcelableUser
abstract class CursorUsersListFragment : ParcelableUsersFragment() {
protected var nextCursor: Long = -1
private set
protected var prevCursor: Long = -1
private set
protected var nextPage = 1
private set
override fun onActivityCreated(savedInstanceState: Bundle?) {
if (savedInstanceState != null) {
nextCursor = savedInstanceState.getLong(EXTRA_NEXT_CURSOR, -1)
prevCursor = savedInstanceState.getLong(EXTRA_PREV_CURSOR, -1)
nextPage = savedInstanceState.getInt(EXTRA_NEXT_PAGE, -1)
}
super.onActivityCreated(savedInstanceState)
}
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
super.onLoaderReset(loader)
}
override fun onLoadFinished(loader: Loader<List<ParcelableUser>?>, data: List<ParcelableUser>?) {
super.onLoadFinished(loader, data)
val cursorLoader = loader as CursorSupportUsersLoader
nextCursor = cursorLoader.nextCursor
prevCursor = cursorLoader.prevCursor
nextPage = cursorLoader.nextPage
}
override fun onLoadMoreContents(@IndicatorPosition position: Long) {
// Only supports load from end, skip START flag
if (position and ILoadMoreSupportAdapter.START != 0L) return
super.onLoadMoreContents(position)
if (position == 0L) return
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor)
loaderArgs.putInt(EXTRA_PAGE, nextPage)
loaderManager.restartLoader(0, loaderArgs, this)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putLong(EXTRA_NEXT_CURSOR, nextCursor)
outState.putLong(EXTRA_PREV_CURSOR, prevCursor)
outState.putInt(EXTRA_NEXT_PAGE, nextPage)
}
abstract override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): CursorSupportUsersLoader
}

View File

@ -13,6 +13,7 @@ import org.mariotaku.microblog.library.statusnet.model.Group
import org.mariotaku.twidere.Constants.* import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SupportTabsAdapter import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.fragment.users.GroupMembersFragment
import org.mariotaku.twidere.model.ParcelableGroup import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.SingleResponse import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -29,7 +29,7 @@ import android.view.MenuItem
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.ComposeActivity import org.mariotaku.twidere.activity.ComposeActivity
import org.mariotaku.twidere.loader.GroupTimelineLoader import org.mariotaku.twidere.loader.statuses.GroupTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
import java.util.* import java.util.*

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.MediaStatusesSearchLoader import org.mariotaku.twidere.loader.statuses.MediaStatusesSearchLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils

View File

@ -34,8 +34,10 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.ParcelableGroup import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.KeyboardShortcutsHandler import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
@ -46,8 +48,12 @@ abstract class ParcelableGroupsFragment : AbsContentListRecyclerViewFragment<Par
LoaderCallbacks<List<ParcelableGroup>?>, GroupAdapterListener, KeyboardShortcutCallback { LoaderCallbacks<List<ParcelableGroup>?>, GroupAdapterListener, KeyboardShortcutCallback {
private lateinit var navigationHelper: RecyclerViewNavigationHelper private lateinit var navigationHelper: RecyclerViewNavigationHelper
val nextCursor: Long = 0
val prevCursor: Long = 0 protected var nextPagination: Pagination? = null
protected var prevPagination: Pagination? = null
protected val data: List<ParcelableGroup>?
get() = adapter.getData()
override var refreshing: Boolean override var refreshing: Boolean
get() { get() {
@ -82,6 +88,10 @@ abstract class ParcelableGroupsFragment : AbsContentListRecyclerViewFragment<Par
if (loader is IExtendedLoader) { if (loader is IExtendedLoader) {
loader.fromUser = false loader.fromUser = false
} }
if (loader is IPaginationLoader) {
nextPagination = loader.nextPagination
prevPagination = loader.prevPagination
}
showContent() showContent()
refreshEnabled = true refreshEnabled = true
refreshing = false refreshing = false
@ -95,17 +105,10 @@ abstract class ParcelableGroupsFragment : AbsContentListRecyclerViewFragment<Par
if (position == 0L) return if (position == 0L) return
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor) loaderArgs.putParcelable(EXTRA_PAGINATION, nextPagination)
loaderManager.restartLoader(0, loaderArgs, this) loaderManager.restartLoader(0, loaderArgs, this)
} }
protected fun removeUsers(vararg ids: Long) {
//TODO remove from adapter
}
val data: List<ParcelableGroup>?
get() = adapter.getData()
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean { override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState) return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
} }

View File

@ -31,7 +31,7 @@ import org.mariotaku.twidere.adapter.ListParcelableStatusesAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.extension.getErrorMessage import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.loader.AbsRequestStatusesLoader import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.BaseRefreshTaskParam import org.mariotaku.twidere.model.BaseRefreshTaskParam
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.RefreshTaskParam import org.mariotaku.twidere.model.RefreshTaskParam

View File

@ -34,10 +34,11 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.adapter.iface.IUserListsAdapter.UserListClickListener import org.mariotaku.twidere.adapter.iface.IUserListsAdapter.UserListClickListener
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.iface.ICursorSupportLoader
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.KeyboardShortcutsHandler import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
@ -47,11 +48,18 @@ import org.mariotaku.twidere.view.holder.UserListViewHolder
abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<ParcelableUserListsAdapter>(), LoaderCallbacks<List<ParcelableUserList>>, UserListClickListener, KeyboardShortcutCallback { abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<ParcelableUserListsAdapter>(), LoaderCallbacks<List<ParcelableUserList>>, UserListClickListener, KeyboardShortcutCallback {
private lateinit var navigationHelper: RecyclerViewNavigationHelper private lateinit var navigationHelper: RecyclerViewNavigationHelper
var nextCursor: Long = 0
var nextPagination: Pagination? = null
private set private set
var prevCursor: Long = 0 var prevPagination: Pagination? = null
private set private set
protected val accountKey: UserKey?
get() = arguments.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val data: List<ParcelableUserList>?
get() = adapter.getData()
override var refreshing: Boolean override var refreshing: Boolean
get() { get() {
if (context == null || isDetached) return false if (context == null || isDetached) return false
@ -69,9 +77,6 @@ abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<
super.setupRecyclerView(context, recyclerView) super.setupRecyclerView(context, recyclerView)
} }
protected val accountKey: UserKey?
get() = arguments.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
protected fun hasMoreData(data: List<ParcelableUserList>?): Boolean { protected fun hasMoreData(data: List<ParcelableUserList>?): Boolean {
return data == null || !data.isEmpty() return data == null || !data.isEmpty()
} }
@ -85,9 +90,9 @@ abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<
if (loader is IExtendedLoader) { if (loader is IExtendedLoader) {
loader.fromUser = false loader.fromUser = false
} }
if (loader is ICursorSupportLoader) { if (loader is IPaginationLoader) {
nextCursor = loader.nextCursor nextPagination = loader.nextPagination
prevCursor = loader.nextCursor prevPagination = loader.nextPagination
} }
showContent() showContent()
refreshEnabled = true refreshEnabled = true
@ -102,17 +107,10 @@ abstract class ParcelableUserListsFragment : AbsContentListRecyclerViewFragment<
if (position == 0L) return if (position == 0L) return
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor) loaderArgs.putParcelable(EXTRA_PAGINATION, nextPagination)
loaderManager.restartLoader(0, loaderArgs, this) loaderManager.restartLoader(0, loaderArgs, this)
} }
protected fun removeUsers(vararg ids: Long) {
//TODO remove from adapter
}
val data: List<ParcelableUserList>?
get() = adapter.getData()
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean { override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState) return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
} }

View File

@ -39,13 +39,15 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserClickListener import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserClickListener
import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_SIMPLE_LAYOUT
import org.mariotaku.twidere.constant.newDocumentApiKey import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.KeyboardShortcutsHandler import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
@ -56,8 +58,32 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
LoaderCallbacks<List<ParcelableUser>?>, UserClickListener, KeyboardShortcutCallback, LoaderCallbacks<List<ParcelableUser>?>, UserClickListener, KeyboardShortcutCallback,
IUsersAdapter.FriendshipClickListener { IUsersAdapter.FriendshipClickListener {
private lateinit var navigationHelper: RecyclerViewNavigationHelper override var refreshing: Boolean
get() {
if (context == null || isDetached) return false
return loaderManager.hasRunningLoadersSafe()
}
set(value) {
super.refreshing = value
}
protected open val userReferral: String?
@Referral
get() = null
protected open val simpleLayout: Boolean
get() = arguments.getBoolean(EXTRA_SIMPLE_LAYOUT)
protected open val showFollow: Boolean
get() = true
protected var nextPagination: Pagination? = null
private set
protected var prevPagination: Pagination? = null
private set
private lateinit var navigationHelper: RecyclerViewNavigationHelper
private val usersBusCallback: Any private val usersBusCallback: Any
init { init {
@ -66,12 +92,16 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
nextPagination = savedInstanceState.getParcelable(EXTRA_NEXT_PAGINATION)
prevPagination = savedInstanceState.getParcelable(EXTRA_PREV_PAGINATION)
}
adapter.userClickListener = this adapter.userClickListener = this
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
this) this)
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderManager.initLoader(0, loaderArgs, this) loaderManager.initLoader(0, loaderArgs, this)
} }
@ -85,21 +115,20 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
super.onStop() super.onStop()
} }
override var refreshing: Boolean override fun onSaveInstanceState(outState: Bundle) {
get() { super.onSaveInstanceState(outState)
if (context == null || isDetached) return false outState.putParcelable(EXTRA_NEXT_PAGINATION, nextPagination)
return loaderManager.hasRunningLoadersSafe() outState.putParcelable(EXTRA_PREV_PAGINATION, prevPagination)
} }
set(value) {
super.refreshing = value
}
override fun onCreateAdapter(context: Context): ParcelableUsersAdapter { override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>?> {
val adapter = ParcelableUsersAdapter(context, Glide.with(this)) val fromUser = args.getBoolean(EXTRA_FROM_USER)
adapter.simpleLayout = simpleLayout args.remove(EXTRA_FROM_USER)
adapter.showFollow = showFollow return onCreateUsersLoader(activity, args, fromUser).apply {
adapter.friendshipClickListener = this if (this is AbsRequestUsersLoader) {
return adapter pagination = args.getParcelable(EXTRA_PAGINATION)
}
}
} }
override fun onLoadFinished(loader: Loader<List<ParcelableUser>?>, data: List<ParcelableUser>?) { override fun onLoadFinished(loader: Loader<List<ParcelableUser>?>, data: List<ParcelableUser>?) {
@ -111,12 +140,41 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
if (loader is IExtendedLoader) { if (loader is IExtendedLoader) {
loader.fromUser = false loader.fromUser = false
} }
if (loader is IPaginationLoader) {
nextPagination = loader.nextPagination
prevPagination = loader.prevPagination
}
showContent() showContent()
refreshEnabled = true refreshEnabled = true
refreshing = false refreshing = false
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE) setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
} }
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
if (loader is IExtendedLoader) {
loader.fromUser = false
}
}
override fun onLoadMoreContents(@ILoadMoreSupportAdapter.IndicatorPosition position: Long) {
// Only supports load from end, skip START flag
if (position and ILoadMoreSupportAdapter.START != 0L) return
super.onLoadMoreContents(position)
if (position == 0L) return
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putParcelable(EXTRA_PAGINATION, nextPagination)
loaderManager.restartLoader(0, loaderArgs, this)
}
override fun onCreateAdapter(context: Context): ParcelableUsersAdapter {
val adapter = ParcelableUsersAdapter(context, Glide.with(this))
adapter.simpleLayout = simpleLayout
adapter.showFollow = showFollow
adapter.friendshipClickListener = this
return adapter
}
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int,
event: KeyEvent, metaState: Int): Boolean { event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState) return navigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
@ -127,23 +185,12 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
return navigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState) return navigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
} }
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int, override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int,
event: KeyEvent, metaState: Int): Boolean { event: KeyEvent, metaState: Int): Boolean {
return navigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState) return navigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
} }
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>?> {
val fromUser = args.getBoolean(IntentConstants.EXTRA_FROM_USER)
args.remove(IntentConstants.EXTRA_FROM_USER)
return onCreateUsersLoader(activity, args, fromUser)
}
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
if (loader is IExtendedLoader) {
loader.fromUser = false
}
}
override fun onUserClick(holder: UserViewHolder, position: Int) { override fun onUserClick(holder: UserViewHolder, position: Int) {
val user = adapter.getUser(position) ?: return val user = adapter.getUser(position) ?: return
IntentUtils.openUserProfile(activity, user, preferences[newDocumentApiKey], userReferral) IntentUtils.openUserProfile(activity, user, preferences[newDocumentApiKey], userReferral)
@ -171,25 +218,12 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
twitterWrapper.destroyMuteAsync(user.account_key, user.key) twitterWrapper.destroyMuteAsync(user.account_key, user.key)
} }
protected open val userReferral: String?
@Referral
get() = null
protected open val simpleLayout: Boolean
get() = arguments.getBoolean(EXTRA_SIMPLE_LAYOUT)
protected open val showFollow: Boolean
get() = true
override fun onUserLongClick(holder: UserViewHolder, position: Int): Boolean { override fun onUserLongClick(holder: UserViewHolder, position: Int): Boolean {
return true return true
} }
protected abstract fun onCreateUsersLoader(context: Context, override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
args: Bundle,
fromUser: Boolean): Loader<List<ParcelableUser>?>
override fun createItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? { layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
val itemDecoration = ExtendedDividerItemDecoration(context, val itemDecoration = ExtendedDividerItemDecoration(context,
(recyclerView.layoutManager as LinearLayoutManager).orientation) (recyclerView.layoutManager as LinearLayoutManager).orientation)
@ -214,9 +248,8 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
return itemDecoration return itemDecoration
} }
private fun findPosition(accountKey: UserKey, userKey: UserKey): Int { abstract fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
return adapter.findPosition(accountKey, userKey) Loader<List<ParcelableUser>?>
}
protected open fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean { protected open fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean {
return false return false
@ -230,6 +263,10 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
return UsersBusCallback() return UsersBusCallback()
} }
private fun findPosition(accountKey: UserKey, userKey: UserKey): Int {
return adapter.findPosition(accountKey, userKey)
}
protected inner class UsersBusCallback { protected inner class UsersBusCallback {
@Subscribe @Subscribe

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.PublicTimelineLoader import org.mariotaku.twidere.loader.statuses.PublicTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
import java.util.* import java.util.*

View File

@ -44,6 +44,7 @@ import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
import org.mariotaku.twidere.fragment.users.SearchUsersFragment
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.analyzer.Search import org.mariotaku.twidere.model.analyzer.Search
import org.mariotaku.twidere.model.tab.DrawableHolder import org.mariotaku.twidere.model.tab.DrawableHolder

View File

@ -1,80 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment
import android.content.Context
import android.os.Bundle
import android.support.v4.content.Loader
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserSearchLoader
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
class SearchUsersFragment : ParcelableUsersFragment() {
private var page = 1
override fun onActivityCreated(savedInstanceState: Bundle?) {
if (savedInstanceState != null) {
page = savedInstanceState.getInt(EXTRA_PAGE, 1)
}
super.onActivityCreated(savedInstanceState)
}
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): Loader<List<ParcelableUser>?> {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val query = args.getString(EXTRA_QUERY)
val page = args.getInt(EXTRA_PAGE, 1)
return UserSearchLoader(context, accountKey, query, page, adapter.getData(), fromUser)
}
override fun onLoadFinished(loader: Loader<List<ParcelableUser>?>, data: List<ParcelableUser>?) {
super.onLoadFinished(loader, data)
if (loader is UserSearchLoader) {
page = loader.page
}
}
override fun onLoadMoreContents(@IndicatorPosition position: Long) {
// Only supports load from end, skip START flag
if (position and ILoadMoreSupportAdapter.START != 0L) return
super.onLoadMoreContents(position)
if (position == 0L) return
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putInt(EXTRA_PAGE, page + 1)
loaderManager.restartLoader<List<ParcelableUser>>(0, loaderArgs, this)
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putInt(EXTRA_PAGE, page)
super.onSaveInstanceState(outState)
}
override fun onDestroyView() {
page = 1
super.onDestroyView()
}
override val userReferral: String? = Referral.SEARCH_RESULT
}

View File

@ -95,7 +95,7 @@ import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.view.calculateSpaceItemHeight import org.mariotaku.twidere.extension.view.calculateSpaceItemHeight
import org.mariotaku.twidere.fragment.AbsStatusesFragment.Companion.handleActionClick import org.mariotaku.twidere.fragment.AbsStatusesFragment.Companion.handleActionClick
import org.mariotaku.twidere.loader.ConversationLoader import org.mariotaku.twidere.loader.statuses.ConversationLoader
import org.mariotaku.twidere.loader.ParcelableStatusLoader import org.mariotaku.twidere.loader.ParcelableStatusLoader
import org.mariotaku.twidere.menu.FavoriteItemProvider import org.mariotaku.twidere.menu.FavoriteItemProvider
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.*

View File

@ -24,7 +24,7 @@ import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.TweetSearchLoader import org.mariotaku.twidere.loader.statuses.TweetSearchLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
import java.io.UnsupportedEncodingException import java.io.UnsupportedEncodingException

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.UserFavoritesLoader import org.mariotaku.twidere.loader.statuses.UserFavoritesLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FavoriteTaskEvent import org.mariotaku.twidere.model.event.FavoriteTaskEvent

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserGroupsLoader import org.mariotaku.twidere.loader.group.UserGroupsLoader
import org.mariotaku.twidere.model.ParcelableGroup import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -16,7 +16,7 @@ class UserGroupsFragment : ParcelableGroupsFragment() {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
return UserGroupsLoader(context, accountKey, userKey, screenName, data) return UserGroupsLoader(context, accountKey, userKey, screenName, adapter.getData())
} }
} }

View File

@ -53,10 +53,13 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.AccountSelectorActivity import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.UserSelectorActivity import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.adapter.SupportTabsAdapter import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.newDocumentApiKey import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.extension.applyTheme import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
import org.mariotaku.twidere.fragment.users.UserListMembersFragment
import org.mariotaku.twidere.fragment.users.UserListSubscribersFragment
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.SingleResponse import org.mariotaku.twidere.model.SingleResponse
@ -201,7 +204,7 @@ class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener,
followItem.setTitle(R.string.action_subscribe) followItem.setTitle(R.string.action_subscribe)
} }
val extensionsIntent = Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST) val extensionsIntent = Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST)
extensionsIntent.setExtrasClassLoader(activity.classLoader) extensionsIntent.setExtrasClassLoader(TwidereApplication::class.java.classLoader)
extensionsIntent.putExtra(EXTRA_USER_LIST, userList) extensionsIntent.putExtra(EXTRA_USER_LIST, userList)
MenuUtils.addIntentToMenu(activity, menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION) MenuUtils.addIntentToMenu(activity, menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION)
} else { } else {

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserListMembershipsLoader import org.mariotaku.twidere.loader.userlists.UserListMembershipsLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -34,8 +34,9 @@ class UserListMembershipsFragment : ParcelableUserListsFragment() {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
val cursor = args.getLong(EXTRA_NEXT_CURSOR, -1) return UserListMembershipsLoader(activity, accountKey, userKey, screenName, data).apply {
return UserListMembershipsLoader(activity, accountKey, userKey, screenName, cursor, data) pagination = args.getParcelable(EXTRA_PAGINATION)
}
} }
} }

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserListSubscriptionsLoader import org.mariotaku.twidere.loader.userlists.UserListSubscriptionsLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -33,8 +33,9 @@ class UserListSubscriptionsFragment : ParcelableUserListsFragment() {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
val cursor = args.getLong(EXTRA_NEXT_CURSOR, -1) return UserListSubscriptionsLoader(activity, accountKey, userKey, screenName, data).apply {
return UserListSubscriptionsLoader(activity, accountKey, userKey, screenName, cursor, data) pagination = args.getParcelable(EXTRA_PAGINATION)
}
} }
} }

View File

@ -24,7 +24,7 @@ import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants import org.mariotaku.twidere.TwidereConstants
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserListTimelineLoader import org.mariotaku.twidere.loader.statuses.UserListTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils

View File

@ -29,7 +29,7 @@ import com.squareup.otto.Subscribe
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.UserListOwnershipsLoader import org.mariotaku.twidere.loader.userlists.UserListOwnershipsLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.UserListDestroyedEvent import org.mariotaku.twidere.model.event.UserListDestroyedEvent
@ -47,7 +47,9 @@ class UserListsOwnershipsFragment : ParcelableUserListsFragment() {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
return UserListOwnershipsLoader(activity, accountKey, userKey, screenName, nextCursor, data) return UserListOwnershipsLoader(activity, accountKey, userKey, screenName, data).apply {
pagination = args.getParcelable(EXTRA_PAGINATION)
}
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.MediaTimelineLoader import org.mariotaku.twidere.loader.statuses.MediaTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -23,7 +23,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v4.content.Loader import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.UserMentionsLoader import org.mariotaku.twidere.loader.statuses.UserMentionsLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils

View File

@ -30,7 +30,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.constant.userTimelineFilterKey import org.mariotaku.twidere.constant.userTimelineFilterKey
import org.mariotaku.twidere.extension.applyTheme import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.loader.UserTimelineLoader import org.mariotaku.twidere.loader.statuses.UserTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.timeline.TimelineFilter import org.mariotaku.twidere.model.timeline.TimelineFilter

View File

@ -26,14 +26,14 @@ import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.adapter.SelectableUsersAdapter import org.mariotaku.twidere.adapter.SelectableUsersAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_COUNT
import org.mariotaku.twidere.extension.applyTheme import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.fragment.* import org.mariotaku.twidere.fragment.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.analyzer.PurchaseFinished import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.util.Analyzer import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.DataStoreUtils import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.premium.ExtraFeaturesService import org.mariotaku.twidere.util.premium.ExtraFeaturesService
@ -46,18 +46,16 @@ import java.lang.ref.WeakReference
abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<SelectableUsersAdapter>(), abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<SelectableUsersAdapter>(),
LoaderManager.LoaderCallbacks<List<ParcelableUser>?> { LoaderManager.LoaderCallbacks<List<ParcelableUser>?> {
protected var nextCursor: Long = -1 protected var nextPagination: Pagination? = null
private set private set
protected var prevCursor: Long = -1 protected var prevPagination: Pagination? = null
private set
protected var nextPage = 1
private set private set
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderManager.initLoader(0, loaderArgs, this) loaderManager.initLoader(0, loaderArgs, this)
} }
@ -126,8 +124,8 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
} }
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>?> { override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>?> {
val fromUser = args.getBoolean(IntentConstants.EXTRA_FROM_USER) val fromUser = args.getBoolean(EXTRA_FROM_USER)
args.remove(IntentConstants.EXTRA_FROM_USER) args.remove(EXTRA_FROM_USER)
return onCreateUsersLoader(context, args, fromUser) return onCreateUsersLoader(context, args, fromUser)
} }
@ -166,10 +164,9 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
refreshEnabled = data.isNullOrEmpty() refreshEnabled = data.isNullOrEmpty()
refreshing = false refreshing = false
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE) setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
val cursorLoader = loader as CursorSupportUsersLoader val cursorLoader = loader as AbsRequestUsersLoader
nextCursor = cursorLoader.nextCursor nextPagination = cursorLoader.nextPagination
prevCursor = cursorLoader.prevCursor prevPagination = cursorLoader.prevPagination
nextPage = cursorLoader.nextPage
activity.supportInvalidateOptionsMenu() activity.supportInvalidateOptionsMenu()
} }
@ -179,9 +176,8 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
super.onLoadMoreContents(position) super.onLoadMoreContents(position)
if (position == 0L) return if (position == 0L) return
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(IntentConstants.EXTRA_NEXT_CURSOR, nextCursor) loaderArgs.putParcelable(EXTRA_NEXT_PAGINATION, nextPagination)
loaderArgs.putInt(IntentConstants.EXTRA_PAGE, nextPage)
loaderManager.restartLoader(0, loaderArgs, this) loaderManager.restartLoader(0, loaderArgs, this)
} }

View File

@ -3,8 +3,9 @@ package org.mariotaku.twidere.fragment.filter
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.constant.IntentConstants.EXTRA_PAGINATION
import org.mariotaku.twidere.loader.UserBlocksLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserBlocksLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
/** /**
@ -14,11 +15,10 @@ import org.mariotaku.twidere.model.UserKey
class FiltersImportBlocksFragment : BaseFiltersImportFragment() { class FiltersImportBlocksFragment : BaseFiltersImportFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey>(IntentConstants.EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(IntentConstants.EXTRA_ACCOUNT_KEY)
val loader = UserBlocksLoader(context, accountKey, adapter.data, fromUser) return UserBlocksLoader(context, accountKey, adapter.data, fromUser).apply {
loader.cursor = nextCursor pagination = args.getParcelable(EXTRA_PAGINATION)
loader.page = nextPage }
return loader
} }
} }

View File

@ -2,21 +2,23 @@ package org.mariotaku.twidere.fragment.filter
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.MutesUsersLoader import org.mariotaku.twidere.loader.users.MutesUsersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
/** /**
* Created by mariotaku on 2016/12/26. * Created by mariotaku on 2016/12/26.
*/ */
class FiltersImportMutesFragment : BaseFiltersImportFragment() { class FiltersImportMutesFragment : BaseFiltersImportFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val loader = MutesUsersLoader(context, accountKey, adapter.data, fromUser) return MutesUsersLoader(context, accountKey, adapter.data, fromUser).apply {
loader.cursor = nextCursor pagination = args.getParcelable(IntentConstants.EXTRA_PAGINATION)
loader.page = nextPage }
return loader
} }
} }

View File

@ -279,7 +279,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
return FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true) return FixedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
} }
override fun createItemDecoration(context: Context, recyclerView: RecyclerView, override fun onCreateItemDecoration(context: Context, recyclerView: RecyclerView,
layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? { layoutManager: LinearLayoutManager): RecyclerView.ItemDecoration? {
return null return null
} }

View File

@ -1,42 +1,40 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.GroupMembersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.GroupMembersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
class GroupMembersFragment : CursorUsersListFragment() { class GroupMembersFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
args: Bundle, fromUser: Boolean): CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val groupId = args.getString(EXTRA_GROUP_ID) val groupId = args.getString(EXTRA_GROUP_ID)
val groupName = args.getString(EXTRA_GROUP_NAME) val groupName = args.getString(EXTRA_GROUP_NAME)
val loader = GroupMembersLoader(context, accountKey, groupId, groupName, adapter.getData(), return GroupMembersLoader(context, accountKey, groupId, groupName, adapter.getData(),
fromUser) fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
} }

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
@ -26,23 +26,21 @@ import org.mariotaku.twidere.TwidereConstants.USER_TYPE_FANFOU_COM
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter import org.mariotaku.twidere.adapter.ParcelableUsersAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.IncomingFriendshipsLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.IncomingFriendshipsLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.view.holder.UserViewHolder import org.mariotaku.twidere.view.holder.UserViewHolder
class IncomingFriendshipsFragment : CursorUsersListFragment(), IUsersAdapter.RequestClickListener { class IncomingFriendshipsFragment : ParcelableUsersFragment(), IUsersAdapter.RequestClickListener {
override val showFollow: Boolean = false override val showFollow: Boolean = false
override fun onCreateUsersLoader(context: Context, args: Bundle, override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
fromUser: Boolean): CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val loader = IncomingFriendshipsLoader(context, accountKey, adapter.getData(), fromUser) return IncomingFriendshipsLoader(context, accountKey, adapter.getData(), fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
override fun onCreateAdapter(context: Context): ParcelableUsersAdapter { override fun onCreateAdapter(context: Context): ParcelableUsersAdapter {

View File

@ -1,41 +1,39 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.MutesUsersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.MutesUsersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
class MutesUsersListFragment : CursorUsersListFragment() { class MutesUsersListFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val loader = MutesUsersLoader(context, accountKey, adapter.getData(), fromUser) return MutesUsersLoader(context, accountKey, adapter.getData(), fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean { override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean {

View File

@ -0,0 +1,43 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.users
import android.content.Context
import android.os.Bundle
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserSearchLoader
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
class SearchUsersFragment : ParcelableUsersFragment() {
override val userReferral: String? = Referral.SEARCH_RESULT
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val query = args.getString(EXTRA_QUERY)
val pagination = args.getParcelable<Pagination?>(EXTRA_PAGINATION)
return UserSearchLoader(context, accountKey, query, adapter.getData(), fromUser)
}
}

View File

@ -1,47 +1,48 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS_ID import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS_ID
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.StatusFavoritersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.StatusFavoritersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
class StatusFavoritersListFragment : CursorUsersListFragment() { class StatusFavoritersListFragment : ParcelableUsersFragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
super.onActivityCreated(savedInstanceState) AbsRequestUsersLoader {
adapter.loadMoreSupportedPosition = ILoadMoreSupportAdapter.NONE
}
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val statusId = args.getString(EXTRA_STATUS_ID) val statusId = args.getString(EXTRA_STATUS_ID)
val loader = StatusFavoritersLoader(context, accountKey, statusId, adapter.getData(), false) return StatusFavoritersLoader(context, accountKey, statusId, adapter.getData(), false)
loader.cursor = nextCursor }
loader.page = nextPage
return loader override fun onCreateAdapter(context: Context): ParcelableUsersAdapter {
return super.onCreateAdapter(context).apply {
loadMoreSupportedPosition = ILoadMoreSupportAdapter.NONE
}
} }
} }

View File

@ -1,44 +1,40 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS_ID import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS_ID
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.StatusRetweetersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.StatusRetweetersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
class StatusRetweetersListFragment : CursorUsersListFragment() { class StatusRetweetersListFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
args: Bundle, AbsRequestUsersLoader {
fromUser: Boolean): CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val statusId = args.getString(EXTRA_STATUS_ID) val statusId = args.getString(EXTRA_STATUS_ID)
val loader = StatusRetweetersLoader(context, accountKey, statusId, adapter.getData(), return StatusRetweetersLoader(context, accountKey, statusId, adapter.getData(), fromUser)
fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
} }

View File

@ -1,42 +1,39 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.UserBlocksLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserBlocksLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
class UserBlocksListFragment : CursorUsersListFragment() { class UserBlocksListFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
args: Bundle, AbsRequestUsersLoader {
fromUser: Boolean): CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val loader = UserBlocksLoader(context, accountKey, adapter.getData(), fromUser) return UserBlocksLoader(context, accountKey, adapter.getData(), fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean { override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean {

View File

@ -1,44 +1,42 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.UserFollowersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserFollowersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
class UserFollowersFragment : CursorUsersListFragment() { class UserFollowersFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
val loader = UserFollowersLoader(context, accountKey, userKey, screenName, return UserFollowersLoader(context, accountKey, userKey, screenName, adapter.getData(),
adapter.getData(), fromUser) fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean { override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean {

View File

@ -1,44 +1,41 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.UserFriendsLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserFriendsLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent import org.mariotaku.twidere.model.event.FriendshipTaskEvent
class UserFriendsFragment : CursorUsersListFragment() { class UserFriendsFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
args: Bundle, fromUser: Boolean): CursorSupportUsersLoader { AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
val loader = UserFriendsLoader(context, accountKey, userKey, screenName, adapter.getData(), return UserFriendsLoader(context, accountKey, userKey, screenName, adapter.getData(), fromUser)
fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean { override fun shouldRemoveUser(position: Int, event: FriendshipTaskEvent): Boolean {

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
@ -31,8 +31,11 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.nameFirstKey import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.DeleteUserListMembersDialogFragment
import org.mariotaku.twidere.loader.UserListMembersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.fragment.UserListFragment
import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserListMembersLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.UserListMembersChangedEvent import org.mariotaku.twidere.model.event.UserListMembersChangedEvent
@ -41,21 +44,16 @@ import org.mariotaku.twidere.view.ExtendedRecyclerView
import org.mariotaku.twidere.view.holder.UserViewHolder import org.mariotaku.twidere.view.holder.UserViewHolder
import java.util.* import java.util.*
class UserListMembersFragment : CursorUsersListFragment() { class UserListMembersFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, val userList: ParcelableUserList?
args: Bundle, fromUser: Boolean): CursorSupportUsersLoader { get() {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val parent = parentFragment
val listId = args.getString(EXTRA_LIST_ID) if (parent is UserListFragment) {
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) return parent.userList
val screenName = args.getString(EXTRA_SCREEN_NAME) }
val listName = args.getString(EXTRA_LIST_NAME) return null
val loader = UserListMembersLoader(context, accountKey, listId, userKey, screenName, }
listName, adapter.getData(), fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
}
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
@ -77,6 +75,17 @@ class UserListMembersFragment : CursorUsersListFragment() {
super.onStop() super.onStop()
} }
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
AbsRequestUsersLoader {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val listId = args.getString(EXTRA_LIST_ID)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME)
val listName = args.getString(EXTRA_LIST_NAME)
return UserListMembersLoader(context, accountKey, listId, userKey, screenName, listName,
adapter.getData(), fromUser)
}
override fun onUserLongClick(holder: UserViewHolder, position: Int): Boolean { override fun onUserLongClick(holder: UserViewHolder, position: Int): Boolean {
return recyclerView.showContextMenuForChild(holder.itemView) return recyclerView.showContextMenuForChild(holder.itemView)
} }
@ -107,15 +116,6 @@ class UserListMembersFragment : CursorUsersListFragment() {
return false return false
} }
val userList: ParcelableUserList?
get() {
val parent = parentFragment
if (parent is UserListFragment) {
return parent.userList
}
return null
}
@Subscribe @Subscribe
fun onUserListMembersChanged(event: UserListMembersChangedEvent) { fun onUserListMembersChanged(event: UserListMembersChangedEvent) {
val userList = event.userList val userList = event.userList

View File

@ -1,44 +1,43 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.users
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.* import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.loader.CursorSupportUsersLoader import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.UserListSubscribersLoader import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.UserListSubscribersLoader
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
class UserListSubscribersFragment : CursorUsersListFragment() { class UserListSubscribersFragment : ParcelableUsersFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): CursorSupportUsersLoader { override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
AbsRequestUsersLoader {
val listId = args.getString(EXTRA_LIST_ID) val listId = args.getString(EXTRA_LIST_ID)
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY) val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME) val screenName = args.getString(EXTRA_SCREEN_NAME)
val listName = args.getString(EXTRA_LIST_NAME) val listName = args.getString(EXTRA_LIST_NAME)
val loader = UserListSubscribersLoader(context, accountKey, return UserListSubscribersLoader(context, accountKey, listId, userKey, screenName, listName,
listId, userKey, screenName, listName, adapter.getData(), fromUser) adapter.getData(), fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
} }
} }

View File

@ -3,11 +3,15 @@ package org.mariotaku.twidere.loader
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.loader.users.UserSearchLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.PaginatedArrayList
import org.mariotaku.twidere.model.pagination.PaginatedList
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
@ -23,7 +27,7 @@ class CacheUserSearchLoader(
private val fromNetwork: Boolean, private val fromNetwork: Boolean,
private val fromCache: Boolean, private val fromCache: Boolean,
fromUser: Boolean fromUser: Boolean
) : UserSearchLoader(context, accountKey, query, 0, null, fromUser) { ) : UserSearchLoader(context, accountKey, query, null, fromUser) {
@Inject @Inject
internal lateinit var userColorNameManager: UserColorNameManager internal lateinit var userColorNameManager: UserColorNameManager
@ -31,9 +35,9 @@ class CacheUserSearchLoader(
GeneralComponent.get(context).inject(this) GeneralComponent.get(context).inject(this)
} }
override fun getUsers(details: AccountDetails): List<ParcelableUser> { override fun getUsers(details: AccountDetails, paging: Paging): PaginatedList<ParcelableUser> {
if (query.isEmpty() || !fromNetwork) return emptyList() if (query.isEmpty() || !fromNetwork) return PaginatedArrayList()
return super.getUsers(details) return super.getUsers(details, paging)
} }
override fun processUsersData(details: AccountDetails, list: MutableList<ParcelableUser>) { override fun processUsersData(details: AccountDetails, list: MutableList<ParcelableUser>) {

View File

@ -1,88 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader
import android.content.Context
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.CursorSupport
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.iface.ICursorSupportLoader
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
abstract class CursorSupportUsersLoader(
context: Context,
accountKey: UserKey?,
data: List<ParcelableUser>?,
fromUser: Boolean
) : AbsRequestUsersLoader(context, accountKey, data, fromUser), ICursorSupportLoader {
var page = -1
override var cursor: Long = 0
val count: Int
override var nextCursor: Long = 0
protected set
override var prevCursor: Long = 0
protected set
var nextPage: Int = 0
protected set
init {
val preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
val loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT)
count = Math.min(100, loadItemLimit)
}
protected fun setCursors(cursor: CursorSupport?) {
if (cursor == null) return
nextCursor = cursor.nextCursor
prevCursor = cursor.previousCursor
}
protected fun incrementPage(users: List<ParcelableUser>) {
if (users.isEmpty()) return
if (page == -1) {
page = 1
}
nextPage = page + 1
}
@Throws(MicroBlogException::class)
protected abstract fun getUsers(details: AccountDetails, paging: Paging): List<ParcelableUser>
@Throws(MicroBlogException::class)
override fun getUsers(details: AccountDetails): List<ParcelableUser> {
val paging = Paging()
paging.count(count)
if (cursor > 0) {
paging.setCursor(cursor)
} else if (page > 1) {
paging.setPage(page)
}
val users = getUsers(details, paging)
incrementPage(users)
return users
}
}

View File

@ -1,95 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader
import android.content.Context
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.microblog.library.mastodon.model.Account
import org.mariotaku.microblog.library.twitter.model.CursorSupport
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
class UserFollowersLoader(
context: Context,
accountKey: UserKey?,
private val userKey: UserKey?,
private val screenName: String?,
data: List<ParcelableUser>?,
fromUser: Boolean
) : CursorSupportUsersLoader(context, accountKey, data, fromUser) {
@Throws(MicroBlogException::class)
override fun getUsers(details: AccountDetails, paging: Paging): List<ParcelableUser> {
when (details.type) {
AccountType.MASTODON -> return getMastodonUsers(details, paging).map {
it.toParcelable(details.key)
}
else -> return getMicroBlogUsers(details, paging).map {
it.toParcelable(details.key, details.type, profileImageSize = profileImageSize)
}
}
}
private fun getMastodonUsers(details: AccountDetails, paging: Paging): List<Account> {
val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java)
if (userKey == null) throw MicroBlogException("Only ID supported")
return mastodon.getFollowers(userKey.id, paging)
}
private fun getMicroBlogUsers(details: AccountDetails, paging: Paging): List<User> {
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
when (details.type) {
AccountType.STATUSNET -> if (userKey != null) {
return microBlog.getStatusesFollowersList(userKey.id, paging).also {
setCursors(it as? CursorSupport)
}
} else if (screenName != null) {
return microBlog.getStatusesFollowersListByScreenName(screenName, paging).also {
setCursors(it as? CursorSupport)
}
}
AccountType.FANFOU -> if (userKey != null) {
return microBlog.getUsersFollowers(userKey.id, paging)
} else if (screenName != null) {
return microBlog.getUsersFollowers(screenName, paging)
}
else -> if (userKey != null) {
return microBlog.getFollowersList(userKey.id, paging).also {
setCursors(it as? CursorSupport)
}
} else if (screenName != null) {
return microBlog.getFollowersListByScreenName(screenName, paging).also {
setCursors(it as? CursorSupport)
}
}
}
throw MicroBlogException("user_id or screen_name required")
}
}

View File

@ -1,86 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader
import android.content.Context
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.microblog.library.mastodon.model.Account
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
class UserFriendsLoader(
context: Context,
accountKey: UserKey?,
private val userKey: UserKey?,
private val screenName: String?,
data: List<ParcelableUser>?,
fromUser: Boolean
) : CursorSupportUsersLoader(context, accountKey, data, fromUser) {
@Throws(MicroBlogException::class)
override fun getUsers(details: AccountDetails, paging: Paging): List<ParcelableUser> {
when (details.type) {
AccountType.MASTODON -> return getMastodonUsers(details, paging).map {
it.toParcelable(details.key)
}
else -> return getMicroBlogUsers(details, paging).map {
it.toParcelable(details.key, details.type, profileImageSize = profileImageSize)
}
}
}
private fun getMastodonUsers(details: AccountDetails, paging: Paging): List<Account> {
val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java)
if (userKey == null) throw MicroBlogException("Only ID supported")
return mastodon.getFollowing(userKey.id, paging)
}
@Throws(MicroBlogException::class)
private fun getMicroBlogUsers(details: AccountDetails, paging: Paging): List<User> {
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
when (details.type) {
AccountType.STATUSNET -> if (userKey != null) {
return microBlog.getStatusesFriendsList(userKey.id, paging)
} else if (screenName != null) {
return microBlog.getStatusesFriendsListByScreenName(screenName, paging)
}
AccountType.FANFOU -> if (userKey != null) {
return microBlog.getUsersFriends(userKey.id, paging)
} else if (screenName != null) {
return microBlog.getUsersFriends(screenName, paging)
}
else -> if (userKey != null) {
return microBlog.getFriendsList(userKey.id, paging)
} else if (screenName != null) {
return microBlog.getFriendsListByScreenName(screenName, paging)
}
}
throw MicroBlogException("user_id or screen_name required")
}
}

View File

@ -1,75 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader
import android.content.Context
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.model.Account
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
class UserListSubscribersLoader(
context: Context,
accountKey: UserKey?,
private val listId: String?,
private val userKey: UserKey?,
private val screenName: String?,
private val listName: String?,
data: List<ParcelableUser>?,
fromUser: Boolean
) : CursorSupportUsersLoader(context, accountKey, data, fromUser) {
@Throws(MicroBlogException::class)
override fun getUsers(details: AccountDetails, paging: Paging): List<ParcelableUser> {
when (details.type) {
AccountType.MASTODON -> return getMastodonUsers(details, paging).map {
it.toParcelable(details.key)
}
else -> return getMicroBlogUsers(details, paging).map {
it.toParcelable(details.key, details.type, profileImageSize = profileImageSize)
}
}
}
private fun getMastodonUsers(details: AccountDetails, paging: Paging): List<Account> {
throw MicroBlogException("Not supported")
}
@Throws(MicroBlogException::class)
private fun getMicroBlogUsers(details: AccountDetails, paging: Paging): List<User> {
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
if (listId != null)
return microBlog.getUserListSubscribers(listId, paging)
else if (userKey != null)
return microBlog.getUserListSubscribers(listName!!.replace(' ', '-'), userKey.id, paging)
else if (screenName != null)
return microBlog.getUserListSubscribersByScreenName(listName!!.replace(' ', '-'), screenName, paging)
throw MicroBlogException("list_id or list_name and user_id (or screen_name) required")
}
}

View File

@ -1,35 +1,36 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.group
import android.content.Context import android.content.Context
import android.support.v4.content.FixedAsyncTaskLoader import android.support.v4.content.FixedAsyncTaskLoader
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.statusnet.model.Group import org.mariotaku.microblog.library.statusnet.model.Group
import org.mariotaku.microblog.library.twitter.model.CursorSupport
import org.mariotaku.microblog.library.twitter.model.PageableResponseList import org.mariotaku.microblog.library.twitter.model.PageableResponseList
import org.mariotaku.twidere.TwidereConstants.LOGTAG import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.loader.iface.ICursorSupportLoader import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.ParcelableGroup import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.ParcelableGroupUtils import org.mariotaku.twidere.model.util.ParcelableGroupUtils
import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.MicroBlogAPIFactory import org.mariotaku.twidere.util.MicroBlogAPIFactory
@ -40,17 +41,19 @@ import java.util.*
abstract class BaseGroupsLoader( abstract class BaseGroupsLoader(
context: Context, context: Context,
protected val accountKey: UserKey, protected val accountKey: UserKey,
override val cursor: Long,
data: List<ParcelableGroup>? data: List<ParcelableGroup>?
) : FixedAsyncTaskLoader<List<ParcelableGroup>>(context), ICursorSupportLoader { ) : FixedAsyncTaskLoader<List<ParcelableGroup>>(context), IPaginationLoader {
override var pagination: Pagination? = null
override final var nextPagination: Pagination? = null
private set
override final var prevPagination: Pagination? = null
private set
protected val data = NoDuplicatesArrayList<ParcelableGroup>() protected val data = NoDuplicatesArrayList<ParcelableGroup>()
override final var nextCursor: Long = 0
private set
override final var prevCursor: Long = 0
private set
init { init {
if (data != null) { if (data != null) {
this.data.addAll(data) this.data.addAll(data)
@ -72,8 +75,8 @@ abstract class BaseGroupsLoader(
if (listLoaded != null) { if (listLoaded != null) {
val listSize = listLoaded.size val listSize = listLoaded.size
if (listLoaded is PageableResponseList<*>) { if (listLoaded is PageableResponseList<*>) {
nextCursor = (listLoaded as CursorSupport).nextCursor nextPagination = CursorPagination.valueOf(listLoaded.nextCursor)
prevCursor = listLoaded.previousCursor prevPagination = CursorPagination.valueOf(listLoaded.previousCursor)
val dataSize = data.size val dataSize = data.size
for (i in 0..listSize - 1) { for (i in 0..listSize - 1) {
val group = listLoaded[i] val group = listLoaded[i]

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.group
import android.content.Context import android.content.Context
@ -34,7 +34,7 @@ class UserGroupsLoader(
private val userKey: UserKey?, private val userKey: UserKey?,
private val screenName: String?, private val screenName: String?,
data: List<ParcelableGroup>? data: List<ParcelableGroup>?
) : BaseGroupsLoader(context, accountKey, 0, data) { ) : BaseGroupsLoader(context, accountKey, data) {
@Throws(MicroBlogException::class) @Throws(MicroBlogException::class)
override fun getGroups(twitter: MicroBlog): ResponseList<Group> { override fun getGroups(twitter: MicroBlog): ResponseList<Group> {

View File

@ -19,13 +19,15 @@
package org.mariotaku.twidere.loader.iface package org.mariotaku.twidere.loader.iface
import org.mariotaku.twidere.model.pagination.Pagination
/** /**
* Created by mariotaku on 15/4/29. * Created by mariotaku on 15/4/29.
*/ */
interface ICursorSupportLoader { interface IPaginationLoader {
val cursor: Long get() = -1 val pagination: Pagination? get() = null
val nextCursor: Long get() = -1 val nextPagination: Pagination? get() = null
val prevCursor: Long get() = -1 val prevPagination: Pagination? get() = null
} }

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.accounts.AccountManager import android.accounts.AccountManager
import android.content.Context import android.content.Context

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase

View File

@ -1,25 +1,26 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import org.mariotaku.twidere.loader.statuses.ParcelableStatusesLoader
import org.mariotaku.twidere.model.ListResponse import org.mariotaku.twidere.model.ListResponse
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -29,6 +29,7 @@ import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -1,27 +1,28 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUSES import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUSES
import org.mariotaku.twidere.loader.statuses.ParcelableStatusesLoader
import org.mariotaku.twidere.model.ListResponse import org.mariotaku.twidere.model.ListResponse
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import java.util.* import java.util.*

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -69,10 +69,10 @@ open class MediaStatusesSearchLoader(
override fun processPaging(details: AccountDetails, loadItemLimit: Int, paging: Paging) { override fun processPaging(details: AccountDetails, loadItemLimit: Int, paging: Paging) {
if (details.type == AccountType.STATUSNET) { if (details.type == AccountType.STATUSNET) {
paging.setRpp(loadItemLimit) paging.rpp(loadItemLimit)
val page = page val page = page
if (page > 0) { if (page > 0) {
paging.setPage(page) paging.page(page)
} }
} else { } else {
super.processPaging(details, loadItemLimit, paging) super.processPaging(details, loadItemLimit, paging)

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -33,6 +33,8 @@ import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.loader.statuses.UserTimelineLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -134,7 +136,7 @@ class MediaTimelineLoader(
private fun getMastodonStatuses(account: AccountDetails, paging: Paging): List<ParcelableStatus> { private fun getMastodonStatuses(account: AccountDetails, paging: Paging): List<ParcelableStatus> {
val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java) val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java)
val option = MastodonTimelineOption() val option = org.mariotaku.microblog.library.mastodon.model.TimelineOption()
option.onlyMedia(true) option.onlyMedia(true)
return UserTimelineLoader.getMastodonStatuses(mastodon, userKey, screenName, paging, return UserTimelineLoader.getMastodonStatuses(mastodon, userKey, screenName, paging,
option).map { it.toParcelable(account.key) } option).map { it.toParcelable(account.key) }

View File

@ -0,0 +1,67 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader.statuses
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.support.annotation.WorkerThread
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.InternalTwitterContentUtils
class NetworkPublicTimelineLoader(
context: Context,
accountKey: UserKey?,
sinceId: String?,
maxId: String?,
adapterData: List<ParcelableStatus>?,
savedStatusesArgs: Array<String>?,
tabPosition: Int,
fromUser: Boolean,
loadingMore: Boolean
) : AbsRequestStatusesLoader(context, accountKey, sinceId, maxId, -1, adapterData, savedStatusesArgs,
tabPosition, fromUser, loadingMore) {
@Throws(MicroBlogException::class)
override fun getStatuses(account: AccountDetails, paging: Paging): List<ParcelableStatus> {
when (account.type) {
AccountType.STATUSNET -> {
val microBlog = account.newMicroBlogInstance(context, MicroBlog::class.java)
return microBlog.getNetworkPublicTimeline(paging).map {
it.toParcelable(account.key, account.type, profileImageSize = profileImageSize)
}
}
else -> throw MicroBlogException("STUB")
}
}
@WorkerThread
override fun shouldFilterStatus(database: SQLiteDatabase, status: ParcelableStatus): Boolean {
return InternalTwitterContentUtils.isFiltered(database, status, true)
}
}

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.support.v4.content.FixedAsyncTaskLoader import android.support.v4.content.FixedAsyncTaskLoader

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -28,6 +28,7 @@ import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -117,10 +117,10 @@ open class TweetSearchLoader(
override fun processPaging(details: AccountDetails, loadItemLimit: Int, paging: Paging) { override fun processPaging(details: AccountDetails, loadItemLimit: Int, paging: Paging) {
if (details.type == AccountType.STATUSNET) { if (details.type == AccountType.STATUSNET) {
paging.setRpp(loadItemLimit) paging.rpp(loadItemLimit)
val page = page val page = page
if (page > 0) { if (page > 0) {
paging.setPage(page) paging.page(page)
} }
} else { } else {
super.processPaging(details, loadItemLimit, paging) super.processPaging(details, loadItemLimit, paging)

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -75,7 +75,7 @@ class UserFavoritesLoader(
AccountType.FANFOU -> { AccountType.FANFOU -> {
paging.setCount(loadItemLimit) paging.setCount(loadItemLimit)
if (page > 0) { if (page > 0) {
paging.setPage(page) paging.page(page)
} }
} }
else -> { else -> {

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -29,6 +29,7 @@ import org.mariotaku.microblog.library.twitter.model.ResponseList
import org.mariotaku.microblog.library.twitter.model.Status import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -1,27 +1,28 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.official import org.mariotaku.twidere.extension.model.official
import org.mariotaku.twidere.loader.statuses.TweetSearchLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.statuses
import android.content.Context import android.content.Context
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
@ -42,6 +42,7 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -101,10 +102,10 @@ class UserTimelineLoader(
status.quoted_source, null, status.quoted_user_key) status.quoted_source, null, status.quoted_user_key)
} }
private fun getMastodonStatuses(account: AccountDetails, paging: Paging): List<MastodonStatus> { private fun getMastodonStatuses(account: AccountDetails, paging: Paging): List<org.mariotaku.microblog.library.mastodon.model.Status> {
val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java) val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java)
val id = userKey?.id ?: throw MicroBlogException("Only ID are supported at this moment") val id = userKey?.id ?: throw MicroBlogException("Only ID are supported at this moment")
val option = MastodonTimelineOption() val option = org.mariotaku.microblog.library.mastodon.model.TimelineOption()
if (timelineFilter != null) { if (timelineFilter != null) {
option.excludeReplies(!timelineFilter.isIncludeReplies) option.excludeReplies(!timelineFilter.isIncludeReplies)
} }
@ -194,7 +195,7 @@ class UserTimelineLoader(
companion object { companion object {
fun getMastodonStatuses(mastodon: Mastodon, userKey: UserKey?, screenName: String?, paging: Paging, fun getMastodonStatuses(mastodon: Mastodon, userKey: UserKey?, screenName: String?, paging: Paging,
option: MastodonTimelineOption?): List<MastodonStatus> { option: org.mariotaku.microblog.library.mastodon.model.TimelineOption?): List<org.mariotaku.microblog.library.mastodon.model.Status> {
val id = userKey?.id ?: throw MicroBlogException("Only ID are supported at this moment") val id = userKey?.id ?: throw MicroBlogException("Only ID are supported at this moment")
return mastodon.getStatuses(id, paging, option) return mastodon.getStatuses(id, paging, option)
} }

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.userlists
import android.accounts.AccountManager import android.accounts.AccountManager
import android.content.Context import android.content.Context
@ -27,7 +27,6 @@ import android.util.Log
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.CursorSupport
import org.mariotaku.microblog.library.twitter.model.PageableResponseList import org.mariotaku.microblog.library.twitter.model.PageableResponseList
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.UserList import org.mariotaku.microblog.library.twitter.model.UserList
@ -35,9 +34,11 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.constant.loadItemLimitKey import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.iface.ICursorSupportLoader import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableUserListUtils import org.mariotaku.twidere.model.util.ParcelableUserListUtils
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList
@ -49,9 +50,8 @@ import javax.inject.Inject
abstract class BaseUserListsLoader( abstract class BaseUserListsLoader(
context: Context, context: Context,
protected val accountKey: UserKey?, protected val accountKey: UserKey?,
override val cursor: Long,
data: List<ParcelableUserList>? data: List<ParcelableUserList>?
) : FixedAsyncTaskLoader<List<ParcelableUserList>>(context), ICursorSupportLoader { ) : FixedAsyncTaskLoader<List<ParcelableUserList>>(context), IPaginationLoader {
@Inject @Inject
lateinit var preferences: SharedPreferences lateinit var preferences: SharedPreferences
@ -59,8 +59,12 @@ abstract class BaseUserListsLoader(
private val profileImageSize = context.getString(R.string.profile_image_size) private val profileImageSize = context.getString(R.string.profile_image_size)
override var nextCursor: Long = 0 override var pagination: Pagination? = null
override var prevCursor: Long = 0
override var nextPagination: Pagination? = null
protected set
override var prevPagination: Pagination? = null
protected set
init { init {
GeneralComponent.get(context).inject(this) GeneralComponent.get(context).inject(this)
@ -81,9 +85,7 @@ abstract class BaseUserListsLoader(
val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java)
val paging = Paging() val paging = Paging()
paging.count(preferences[loadItemLimitKey].coerceIn(0, 100)) paging.count(preferences[loadItemLimitKey].coerceIn(0, 100))
if (cursor > 0) { pagination?.applyTo(paging)
paging.cursor(cursor)
}
listLoaded = getUserLists(twitter, paging) listLoaded = getUserLists(twitter, paging)
} catch (e: MicroBlogException) { } catch (e: MicroBlogException) {
Log.w(LOGTAG, e) Log.w(LOGTAG, e)
@ -92,8 +94,8 @@ abstract class BaseUserListsLoader(
if (listLoaded != null) { if (listLoaded != null) {
val listSize = listLoaded.size val listSize = listLoaded.size
if (listLoaded is PageableResponseList<*>) { if (listLoaded is PageableResponseList<*>) {
nextCursor = (listLoaded as CursorSupport).nextCursor nextPagination = CursorPagination.valueOf(listLoaded.nextCursor)
prevCursor = listLoaded.previousCursor prevPagination = CursorPagination.valueOf(listLoaded.previousCursor)
val dataSize = data.size val dataSize = data.size
for (i in 0..listSize - 1) { for (i in 0..listSize - 1) {
val list = listLoaded[i] val list = listLoaded[i]

View File

@ -1,23 +1,23 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.userlists
import android.content.Context import android.content.Context
@ -26,6 +26,7 @@ import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.PageableResponseList import org.mariotaku.microblog.library.twitter.model.PageableResponseList
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.UserList import org.mariotaku.microblog.library.twitter.model.UserList
import org.mariotaku.twidere.loader.userlists.BaseUserListsLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -34,9 +35,8 @@ class UserListMembershipsLoader(
accountKey: UserKey?, accountKey: UserKey?,
private val userKey: UserKey?, private val userKey: UserKey?,
private val screenName: String?, private val screenName: String?,
cursor: Long,
data: List<ParcelableUserList>? data: List<ParcelableUserList>?
) : BaseUserListsLoader(context, accountKey, cursor, data) { ) : BaseUserListsLoader(context, accountKey, data) {
@Throws(MicroBlogException::class) @Throws(MicroBlogException::class)
override fun getUserLists(twitter: MicroBlog, paging: Paging): PageableResponseList<UserList> { override fun getUserLists(twitter: MicroBlog, paging: Paging): PageableResponseList<UserList> {

View File

@ -1,29 +1,30 @@
/* /*
* Twidere - Twitter client for Android * Twidere - Twitter client for Android
* *
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader.userlists
import android.content.Context import android.content.Context
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.UserList import org.mariotaku.microblog.library.twitter.model.UserList
import org.mariotaku.twidere.loader.userlists.BaseUserListsLoader
import org.mariotaku.twidere.model.ParcelableUserList import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -32,9 +33,8 @@ class UserListOwnershipsLoader(
accountKey: UserKey?, accountKey: UserKey?,
private val userKey: UserKey?, private val userKey: UserKey?,
private val screenName: String?, private val screenName: String?,
cursor: Long,
data: List<ParcelableUserList>? data: List<ParcelableUserList>?
) : BaseUserListsLoader(context, accountKey, cursor, data) { ) : BaseUserListsLoader(context, accountKey, data) {
@Throws(MicroBlogException::class) @Throws(MicroBlogException::class)
override fun getUserLists(twitter: MicroBlog, paging: Paging): List<UserList> { override fun getUserLists(twitter: MicroBlog, paging: Paging): List<UserList> {

Some files were not shown because too many files have changed in this diff Show More