Account timelines
This commit is contained in:
parent
ba75aa6d91
commit
dc836b58f8
|
@ -32,10 +32,12 @@ dependencies {
|
||||||
implementation 'me.grishka.litex:recyclerview:1.2.1'
|
implementation 'me.grishka.litex:recyclerview:1.2.1'
|
||||||
implementation 'me.grishka.litex:swiperefreshlayout:1.1.0'
|
implementation 'me.grishka.litex:swiperefreshlayout:1.1.0'
|
||||||
implementation 'me.grishka.litex:browser:1.4.0'
|
implementation 'me.grishka.litex:browser:1.4.0'
|
||||||
implementation 'me.grishka.appkit:appkit:1.1.1'
|
implementation 'me.grishka.appkit:appkit:1.2'
|
||||||
implementation 'com.google.code.gson:gson:2.8.9'
|
implementation 'com.google.code.gson:gson:2.8.9'
|
||||||
implementation 'org.jsoup:jsoup:1.14.3'
|
implementation 'org.jsoup:jsoup:1.14.3'
|
||||||
implementation 'com.squareup:otto:1.3.8'
|
implementation 'com.squareup:otto:1.3.8'
|
||||||
implementation 'de.psdev:async-otto:1.0.3'
|
implementation 'de.psdev:async-otto:1.0.3'
|
||||||
|
implementation 'org.parceler:parceler-api:1.1.12'
|
||||||
|
annotationProcessor 'org.parceler:parceler:1.1.12'
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetAccountStatuses extends MastodonAPIRequest<List<Status>>{
|
||||||
|
public GetAccountStatuses(String id, String maxID, String minID, int limit){
|
||||||
|
super(HttpMethod.GET, "/accounts/"+id+"/statuses", new TypeToken<>(){});
|
||||||
|
if(maxID!=null)
|
||||||
|
addQueryParameter("max_id", maxID);
|
||||||
|
if(minID!=null)
|
||||||
|
addQueryParameter("min_id", minID);
|
||||||
|
if(limit>0)
|
||||||
|
addQueryParameter("limit", ""+limit);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,14 +21,12 @@ import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.SimpleCallback;
|
import me.grishka.appkit.api.SimpleCallback;
|
||||||
|
|
||||||
public class HomeTimelineFragment extends StatusListFragment{
|
public class HomeTimelineFragment extends StatusListFragment{
|
||||||
private String accountID;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity){
|
public void onAttach(Activity activity){
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
setTitle(R.string.app_name);
|
setTitle(R.string.app_name);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
accountID=getArguments().getString("account");
|
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
||||||
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.SimpleCallback;
|
||||||
|
|
||||||
|
public class ProfileFragment extends StatusListFragment{
|
||||||
|
private Account user;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity){
|
||||||
|
super.onAttach(activity);
|
||||||
|
user=Parcels.unwrap(getArguments().getParcelable("profileAccount"));
|
||||||
|
setTitle("@"+user.acct);
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLoadData(int offset, int count){
|
||||||
|
String maxID;
|
||||||
|
if(offset>0 && !preloadedData.isEmpty())
|
||||||
|
maxID=preloadedData.get(preloadedData.size()-1).id;
|
||||||
|
else if(offset>0 && !data.isEmpty())
|
||||||
|
maxID=data.get(data.size()-1).id;
|
||||||
|
else
|
||||||
|
maxID=null;
|
||||||
|
currentRequest=new GetAccountStatuses(user.id, maxID, null, count)
|
||||||
|
.setCallback(new SimpleCallback<>(this){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<Status> result){
|
||||||
|
onDataLoaded(result, !result.isEmpty());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exec(accountID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
@ -19,7 +20,8 @@ import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
public abstract class StatusListFragment extends BaseRecyclerFragment<Status>{
|
public abstract class StatusListFragment extends BaseRecyclerFragment<Status>{
|
||||||
protected ArrayList<StatusDisplayItem> displayItems=new ArrayList<>();
|
protected ArrayList<StatusDisplayItem> displayItems=new ArrayList<>();
|
||||||
private DisplayItemsAdapter adapter;
|
protected DisplayItemsAdapter adapter;
|
||||||
|
protected String accountID;
|
||||||
|
|
||||||
public StatusListFragment(){
|
public StatusListFragment(){
|
||||||
super(20);
|
super(20);
|
||||||
|
@ -30,11 +32,17 @@ public abstract class StatusListFragment extends BaseRecyclerFragment<Status>{
|
||||||
return adapter=new DisplayItemsAdapter();
|
return adapter=new DisplayItemsAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity){
|
||||||
|
super.onAttach(activity);
|
||||||
|
accountID=getArguments().getString("account");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAppendItems(List<Status> items){
|
public void onAppendItems(List<Status> items){
|
||||||
super.onAppendItems(items);
|
super.onAppendItems(items);
|
||||||
for(Status s:items){
|
for(Status s:items){
|
||||||
displayItems.addAll(StatusDisplayItem.buildItems(this, s));
|
displayItems.addAll(StatusDisplayItem.buildItems(this, s, accountID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +56,7 @@ public abstract class StatusListFragment extends BaseRecyclerFragment<Status>{
|
||||||
data.addAll(0, items);
|
data.addAll(0, items);
|
||||||
int offset=0;
|
int offset=0;
|
||||||
for(Status s:items){
|
for(Status s:items){
|
||||||
List<StatusDisplayItem> toAdd=StatusDisplayItem.buildItems(this, s);
|
List<StatusDisplayItem> toAdd=StatusDisplayItem.buildItems(this, s, accountID);
|
||||||
displayItems.addAll(offset, toAdd);
|
displayItems.addAll(offset, toAdd);
|
||||||
offset+=toAdd.size();
|
offset+=toAdd.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.joinmastodon.android.model;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
@ -10,6 +11,7 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Represents a user of Mastodon and their associated profile.
|
* Represents a user of Mastodon and their associated profile.
|
||||||
*/
|
*/
|
||||||
|
@Parcel
|
||||||
public class Account extends BaseModel{
|
public class Account extends BaseModel{
|
||||||
// Base attributes
|
// Base attributes
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package org.joinmastodon.android.model;
|
package org.joinmastodon.android.model;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a profile field as a name-value pair with optional verification.
|
* Represents a profile field as a name-value pair with optional verification.
|
||||||
*/
|
*/
|
||||||
|
@Parcel
|
||||||
public class AccountField extends BaseModel{
|
public class AccountField extends BaseModel{
|
||||||
/**
|
/**
|
||||||
* The key of a given field's key-value pair.
|
* The key of a given field's key-value pair.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package org.joinmastodon.android.model;
|
package org.joinmastodon.android.model;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a custom emoji.
|
* Represents a custom emoji.
|
||||||
*/
|
*/
|
||||||
|
@Parcel
|
||||||
public class Emoji extends BaseModel{
|
public class Emoji extends BaseModel{
|
||||||
/**
|
/**
|
||||||
* The name of the custom emoji.
|
* The name of the custom emoji.
|
||||||
|
|
|
@ -2,12 +2,14 @@ package org.joinmastodon.android.model;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents display or publishing preferences of user's own account. Returned as an additional entity when verifying and updated credentials, as an attribute of Account.
|
* Represents display or publishing preferences of user's own account. Returned as an additional entity when verifying and updated credentials, as an attribute of Account.
|
||||||
*/
|
*/
|
||||||
|
@Parcel
|
||||||
public class Source extends BaseModel{
|
public class Source extends BaseModel{
|
||||||
/**
|
/**
|
||||||
* Profile bio.
|
* Profile bio.
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.graphics.Bitmap;
|
import android.app.Fragment;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||||
|
@ -23,12 +28,16 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||||
private Account user;
|
private Account user;
|
||||||
private Instant createdAt;
|
private Instant createdAt;
|
||||||
private ImageLoaderRequest avaRequest;
|
private ImageLoaderRequest avaRequest;
|
||||||
|
private Fragment parentFragment;
|
||||||
|
private String accountID;
|
||||||
|
|
||||||
public HeaderStatusDisplayItem(Status status, Account user, Instant createdAt){
|
public HeaderStatusDisplayItem(Status status, Account user, Instant createdAt, Fragment parentFragment, String accountID){
|
||||||
super(status);
|
super(status);
|
||||||
this.user=user;
|
this.user=user;
|
||||||
this.createdAt=createdAt;
|
this.createdAt=createdAt;
|
||||||
avaRequest=new UrlImageLoaderRequest(user.avatar);
|
avaRequest=new UrlImageLoaderRequest(user.avatar);
|
||||||
|
this.parentFragment=parentFragment;
|
||||||
|
this.accountID=accountID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -54,6 +63,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||||
name=findViewById(R.id.name);
|
name=findViewById(R.id.name);
|
||||||
subtitle=findViewById(R.id.subtitle);
|
subtitle=findViewById(R.id.subtitle);
|
||||||
avatar=findViewById(R.id.avatar);
|
avatar=findViewById(R.id.avatar);
|
||||||
|
avatar.setOnClickListener(this::onAvaClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,5 +83,12 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
||||||
public void clearImage(int index){
|
public void clearImage(int index){
|
||||||
avatar.setImageBitmap(null);
|
avatar.setImageBitmap(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onAvaClick(View v){
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putString("account", item.accountID);
|
||||||
|
args.putParcelable("profileAccount", Parcels.wrap(item.user));
|
||||||
|
Nav.go(item.parentFragment.getActivity(), ProfileFragment.class, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,13 @@ public abstract class StatusDisplayItem{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<StatusDisplayItem> buildItems(Fragment fragment, Status status){
|
public static List<StatusDisplayItem> buildItems(Fragment fragment, Status status, String accountID){
|
||||||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||||
Status statusForContent=status.reblog==null ? status : status.reblog;
|
Status statusForContent=status.reblog==null ? status : status.reblog;
|
||||||
if(status.reblog!=null){
|
if(status.reblog!=null){
|
||||||
items.add(new ReblogOrReplyLineStatusDisplayItem(status));
|
items.add(new ReblogOrReplyLineStatusDisplayItem(status));
|
||||||
}
|
}
|
||||||
items.add(new HeaderStatusDisplayItem(status, statusForContent.account, statusForContent.createdAt));
|
items.add(new HeaderStatusDisplayItem(status, statusForContent.account, statusForContent.createdAt, fragment, accountID));
|
||||||
if(!TextUtils.isEmpty(statusForContent.content))
|
if(!TextUtils.isEmpty(statusForContent.content))
|
||||||
items.add(new TextStatusDisplayItem(status, HtmlParser.parse(statusForContent.content, statusForContent.emojis), fragment));
|
items.add(new TextStatusDisplayItem(status, HtmlParser.parse(statusForContent.content, statusForContent.emojis), fragment));
|
||||||
for(Attachment attachment:statusForContent.mediaAttachments){
|
for(Attachment attachment:statusForContent.mediaAttachments){
|
||||||
|
|
Loading…
Reference in New Issue