fedilab-Android-App/app/src/main/java/app/fedilab/android/client/Entities/Account.java

1005 lines
40 KiB
Java
Raw Normal View History

2017-05-05 16:36:04 +02:00
/* Copyright 2017 Thomas Schneider
*
2019-05-18 11:10:30 +02:00
* This file is a part of Fedilab
2017-05-05 16:36:04 +02:00
*
* 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.
*
2019-05-18 11:10:30 +02:00
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
2017-05-05 16:36:04 +02:00
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
2019-05-18 11:10:30 +02:00
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
2017-05-05 16:36:04 +02:00
* see <http://www.gnu.org/licenses>. */
2019-05-18 11:10:30 +02:00
package app.fedilab.android.client.Entities;
2017-05-05 16:36:04 +02:00
2018-08-15 10:00:24 +02:00
import android.app.Activity;
import android.content.Context;
2018-11-15 19:09:44 +01:00
import android.content.Intent;
2018-12-31 12:06:50 +01:00
import android.content.SharedPreferences;
2018-08-15 10:00:24 +02:00
import android.graphics.Bitmap;
2018-12-31 12:06:50 +01:00
import android.net.Uri;
2018-10-24 18:29:12 +02:00
import android.os.Build;
import android.os.Bundle;
2017-05-26 17:20:36 +02:00
import android.os.Parcel;
import android.os.Parcelable;
2019-06-11 19:38:26 +02:00
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
2018-10-24 18:29:12 +02:00
import android.text.Html;
2018-08-15 10:00:24 +02:00
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
2018-11-21 14:55:06 +01:00
import android.text.TextUtils;
import android.text.style.ClickableSpan;
2018-08-15 10:00:24 +02:00
import android.text.style.ImageSpan;
2018-12-31 12:06:50 +01:00
import android.text.style.URLSpan;
2018-12-31 16:11:44 +01:00
import android.util.Patterns;
import android.view.View;
import android.widget.Toast;
2017-05-26 17:20:36 +02:00
2018-08-15 10:00:24 +02:00
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
2019-01-24 11:49:23 +01:00
import java.util.ArrayList;
2017-05-05 16:36:04 +02:00
import java.util.Date;
2018-08-15 14:31:15 +02:00
import java.util.Iterator;
2018-10-24 15:44:57 +02:00
import java.util.LinkedHashMap;
2018-08-15 10:00:24 +02:00
import java.util.List;
import java.util.Map;
2018-12-31 12:06:50 +01:00
import java.util.regex.Matcher;
2019-01-24 11:49:23 +01:00
import java.util.regex.Pattern;
2017-05-05 16:36:04 +02:00
import es.dmoral.toasty.Toasty;
2019-05-18 11:10:30 +02:00
import app.fedilab.android.R;
import app.fedilab.android.activities.HashTagActivity;
import app.fedilab.android.activities.ShowAccountActivity;
import app.fedilab.android.helper.CrossActions;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnRetrieveEmojiAccountInterface;
2018-08-15 14:31:15 +02:00
2019-06-11 19:38:26 +02:00
import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY;
2019-05-18 11:10:30 +02:00
import static app.fedilab.android.helper.Helper.THEME_BLACK;
import static app.fedilab.android.helper.Helper.THEME_DARK;
import static app.fedilab.android.helper.Helper.THEME_LIGHT;
import static app.fedilab.android.helper.Helper.hashtagPattern;
2018-10-24 18:29:12 +02:00
2017-05-05 16:36:04 +02:00
/**
* Created by Thomas on 23/04/2017.
2017-05-26 17:20:36 +02:00
* Manage accounts
2017-05-05 16:36:04 +02:00
*/
2017-12-15 18:03:06 +01:00
public class Account implements Parcelable {
2017-05-05 16:36:04 +02:00
private String id;
2019-01-03 18:12:24 +01:00
private String uuid;
2017-05-05 16:36:04 +02:00
private String username;
2018-08-17 11:53:21 +02:00
private SpannableString displayNameSpan;
2017-05-05 16:36:04 +02:00
private String acct;
2018-12-24 11:47:49 +01:00
private String display_name, stored_displayname;
2017-05-05 16:36:04 +02:00
private boolean locked;
private Date created_at;
2019-01-29 11:52:54 +01:00
private Date updated_at;
2017-05-05 16:36:04 +02:00
private int followers_count;
private int following_count;
private int statuses_count;
private String followers_count_str;
private String following_count_str;
private String statuses_count_str;
2017-05-05 16:36:04 +02:00
private String note;
2018-08-15 10:00:24 +02:00
private SpannableString noteSpan;
2017-05-05 16:36:04 +02:00
private String url;
private String avatar;
private String avatar_static;
private String header;
private String header_static;
private String token;
private String instance;
2017-09-03 10:36:27 +02:00
private boolean isFollowing;
2017-09-17 11:28:50 +02:00
private followAction followType = followAction.NOTHING;
private boolean isMakingAction = false;
2017-12-17 08:56:09 +01:00
private Account moved_to_account;
private boolean muting_notifications;
private int metaDataSize;
2018-09-27 19:33:22 +02:00
private int metaDataSizeVerified;
2018-10-31 18:41:15 +01:00
private LinkedHashMap<String, String> fields;
private LinkedHashMap<String, Boolean> fieldsVerified;
private LinkedHashMap<SpannableString, SpannableString> fieldsSpan;
2018-08-15 10:00:24 +02:00
private List<Emojis> emojis;
private String host;
2018-12-22 11:08:04 +01:00
private boolean isBot;
2019-01-02 19:39:40 +01:00
private String social;
private String client_id;
private String client_secret;
private String refresh_token;
2019-01-27 11:02:53 +01:00
private boolean isModerator = false;
private boolean isAdmin = false;
private String privacy = "public";
private boolean sensitive = false;
2018-11-21 14:55:06 +01:00
2019-01-14 09:48:01 +01:00
2019-01-16 13:47:41 +01:00
@Override
public int describeContents() {
return 0;
2018-11-21 14:55:06 +01:00
}
@Override
public void writeToParcel(Parcel dest, int flags) {
2019-01-16 13:47:41 +01:00
dest.writeString(this.id);
dest.writeString(this.uuid);
dest.writeString(this.username);
TextUtils.writeToParcel(this.displayNameSpan, dest, flags);
dest.writeString(this.acct);
dest.writeString(this.display_name);
dest.writeString(this.stored_displayname);
dest.writeByte(this.locked ? (byte) 1 : (byte) 0);
dest.writeLong(this.created_at != null ? this.created_at.getTime() : -1);
2019-01-29 11:52:54 +01:00
dest.writeLong(this.updated_at != null ? this.updated_at.getTime() : -1);
2019-01-16 13:47:41 +01:00
dest.writeInt(this.followers_count);
dest.writeInt(this.following_count);
dest.writeInt(this.statuses_count);
dest.writeString(this.followers_count_str);
dest.writeString(this.following_count_str);
dest.writeString(this.statuses_count_str);
dest.writeString(this.note);
TextUtils.writeToParcel(this.noteSpan, dest, flags);
dest.writeString(this.url);
dest.writeString(this.avatar);
dest.writeString(this.avatar_static);
dest.writeString(this.header);
dest.writeString(this.header_static);
dest.writeString(this.token);
dest.writeString(this.instance);
dest.writeByte(this.isFollowing ? (byte) 1 : (byte) 0);
dest.writeInt(this.followType == null ? -1 : this.followType.ordinal());
dest.writeByte(this.isMakingAction ? (byte) 1 : (byte) 0);
dest.writeParcelable(this.moved_to_account, flags);
dest.writeByte(this.muting_notifications ? (byte) 1 : (byte) 0);
dest.writeInt(this.metaDataSize);
dest.writeInt(this.metaDataSizeVerified);
dest.writeSerializable(this.fields);
dest.writeSerializable(this.fieldsVerified);
dest.writeSerializable(this.fieldsSpan);
dest.writeTypedList(this.emojis);
dest.writeString(this.host);
dest.writeByte(this.isBot ? (byte) 1 : (byte) 0);
dest.writeString(this.social);
dest.writeString(this.client_id);
dest.writeString(this.client_secret);
dest.writeString(this.refresh_token);
2019-01-27 11:02:53 +01:00
dest.writeByte(this.isModerator ? (byte) 1 : (byte) 0);
dest.writeByte(this.isAdmin ? (byte) 1 : (byte) 0);
dest.writeString(this.privacy);
dest.writeByte(this.sensitive ? (byte) 1 : (byte) 0);
2019-01-16 13:47:41 +01:00
}
public Account() {
}
protected Account(Parcel in) {
this.id = in.readString();
this.uuid = in.readString();
this.username = in.readString();
this.displayNameSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
this.acct = in.readString();
this.display_name = in.readString();
this.stored_displayname = in.readString();
this.locked = in.readByte() != 0;
long tmpCreated_at = in.readLong();
this.created_at = tmpCreated_at == -1 ? null : new Date(tmpCreated_at);
2019-01-29 11:52:54 +01:00
long tmpUpdated_at = in.readLong();
this.updated_at = tmpUpdated_at == -1 ? null : new Date(tmpUpdated_at);
2019-01-16 13:47:41 +01:00
this.followers_count = in.readInt();
this.following_count = in.readInt();
this.statuses_count = in.readInt();
this.followers_count_str = in.readString();
this.following_count_str = in.readString();
this.statuses_count_str = in.readString();
this.note = in.readString();
this.noteSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
this.url = in.readString();
this.avatar = in.readString();
this.avatar_static = in.readString();
this.header = in.readString();
this.header_static = in.readString();
this.token = in.readString();
this.instance = in.readString();
this.isFollowing = in.readByte() != 0;
int tmpFollowType = in.readInt();
this.followType = tmpFollowType == -1 ? null : followAction.values()[tmpFollowType];
this.isMakingAction = in.readByte() != 0;
this.moved_to_account = in.readParcelable(Account.class.getClassLoader());
this.muting_notifications = in.readByte() != 0;
this.metaDataSize = in.readInt();
this.metaDataSizeVerified = in.readInt();
this.fields = (LinkedHashMap<String, String>) in.readSerializable();
this.fieldsVerified = (LinkedHashMap<String, Boolean>) in.readSerializable();
this.fieldsSpan = (LinkedHashMap<SpannableString, SpannableString>) in.readSerializable();
this.emojis = in.createTypedArrayList(Emojis.CREATOR);
this.host = in.readString();
this.isBot = in.readByte() != 0;
this.social = in.readString();
this.client_id = in.readString();
this.client_secret = in.readString();
this.refresh_token = in.readString();
2019-01-27 11:02:53 +01:00
this.isModerator = in.readByte() != 0;
this.isAdmin = in.readByte() != 0;
this.privacy = in.readString();
this.sensitive =in.readByte() != 0;
2019-01-16 13:47:41 +01:00
}
public static final Creator<Account> CREATOR = new Creator<Account>() {
@Override
public Account createFromParcel(Parcel source) {
return new Account(source);
2018-11-21 14:55:06 +01:00
}
2019-01-16 13:47:41 +01:00
@Override
public Account[] newArray(int size) {
return new Account[size];
2018-11-21 14:55:06 +01:00
}
2019-01-16 13:47:41 +01:00
};
2018-11-21 14:55:06 +01:00
2017-09-17 11:28:50 +02:00
public followAction getFollowType() {
return followType;
}
public void setFollowType(followAction followType) {
this.followType = followType;
}
public boolean isMakingAction() {
return isMakingAction;
}
public void setMakingAction(boolean makingAction) {
isMakingAction = makingAction;
}
2017-12-17 08:56:09 +01:00
public Account getMoved_to_account() {
return moved_to_account;
}
public void setMoved_to_account(Account moved_to_account) {
this.moved_to_account = moved_to_account;
}
public boolean isMuting_notifications() {
return muting_notifications;
}
public void setMuting_notifications(boolean muting_notifications) {
this.muting_notifications = muting_notifications;
}
2018-10-24 15:44:57 +02:00
public void setFields(LinkedHashMap<String, String> fields) {
2018-08-15 14:31:15 +02:00
this.fields = fields;
}
2018-10-24 15:44:57 +02:00
public LinkedHashMap<String, String> getFields() {
return fields;
}
2018-10-24 15:44:57 +02:00
public void setFieldsSpan(LinkedHashMap<SpannableString, SpannableString> fieldsSpan) {
2018-08-15 14:31:15 +02:00
this.fieldsSpan = fieldsSpan;
}
2018-08-15 14:31:15 +02:00
2018-10-24 15:44:57 +02:00
public LinkedHashMap<SpannableString, SpannableString> getFieldsSpan() {
2018-08-15 14:31:15 +02:00
return fieldsSpan;
}
2018-10-24 15:44:57 +02:00
public LinkedHashMap<String, Boolean> getFieldsVerified() {
2018-09-27 19:33:22 +02:00
return fieldsVerified;
}
2018-10-24 15:44:57 +02:00
public void setFieldsVerified(LinkedHashMap<String, Boolean> fieldsVerified) {
2018-09-27 19:33:22 +02:00
this.fieldsVerified = fieldsVerified;
}
2018-08-15 14:31:15 +02:00
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
2018-12-22 11:08:04 +01:00
public boolean isBot() {
return isBot;
}
public void setBot(boolean bot) {
isBot = bot;
}
2018-12-24 11:47:49 +01:00
public String getStored_displayname() {
return stored_displayname;
}
public void setStored_displayname(String stored_displayname) {
this.stored_displayname = stored_displayname;
}
2019-01-02 19:39:40 +01:00
public String getSocial() {
return social;
}
public void setSocial(String social) {
this.social = social;
}
2019-01-03 18:12:24 +01:00
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getClient_id() {
return client_id;
}
public void setClient_id(String client_id) {
this.client_id = client_id;
}
public String getClient_secret() {
return client_secret;
}
public void setClient_secret(String client_secret) {
this.client_secret = client_secret;
}
public String getRefresh_token() {
return refresh_token;
}
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
2019-01-27 11:02:53 +01:00
public boolean isModerator() {
return isModerator;
}
public void setModerator(boolean moderator) {
isModerator = moderator;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean admin) {
isAdmin = admin;
}
2019-01-29 11:52:54 +01:00
public Date getUpdated_at() {
return updated_at;
}
public void setUpdated_at(Date updated_at) {
this.updated_at = updated_at;
}
public String getPrivacy() {
return privacy;
}
public void setPrivacy(String privacy) {
this.privacy = privacy;
}
public boolean isSensitive() {
return sensitive;
}
public void setSensitive(boolean sensitive) {
this.sensitive = sensitive;
}
2018-08-15 14:31:15 +02:00
2017-09-17 11:28:50 +02:00
public enum followAction{
FOLLOW,
NOT_FOLLOW,
BLOCK,
MUTE,
REQUEST_SENT,
NOTHING
}
2017-05-05 16:36:04 +02:00
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
2018-09-08 15:34:25 +02:00
public SpannableString getdisplayNameSpan() {
2018-08-17 11:53:21 +02:00
return displayNameSpan;
}
2018-09-08 15:34:25 +02:00
public void setdisplayNameSpan(SpannableString displayNameSpan) {
2018-08-17 11:53:21 +02:00
this.displayNameSpan = displayNameSpan;
}
2017-05-05 16:36:04 +02:00
public String getAcct() {
return acct;
}
public void setAcct(String acct) {
this.acct = acct;
}
public String getDisplay_name() {
return display_name;
}
public void setDisplay_name(String display_name) {
this.display_name = display_name;
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public Date getCreated_at() {
return created_at;
}
public void setCreated_at(Date created_at) {
this.created_at = created_at;
}
public int getFollowers_count() {
return followers_count;
}
public void setFollowers_count(int followers_count) {
this.followers_count = followers_count;
}
public int getFollowing_count() {
return following_count;
}
public void setFollowing_count(int following_count) {
this.following_count = following_count;
}
public int getStatuses_count() {
return statuses_count;
}
public void setStatuses_count(int statuses_count) {
this.statuses_count = statuses_count;
}
2018-08-15 10:00:24 +02:00
public SpannableString getNoteSpan() {
return noteSpan;
}
public void setNoteSpan(SpannableString noteSpan) {
this.noteSpan = noteSpan;
}
2017-05-05 16:36:04 +02:00
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getAvatar_static() {
return avatar_static;
}
public void setAvatar_static(String avatar_static) {
this.avatar_static = avatar_static;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getHeader_static() {
return header_static;
}
public void setHeader_static(String header_static) {
this.header_static = header_static;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getInstance() {
return instance;
}
public void setInstance(String instance) {
this.instance = instance;
}
2017-05-26 17:20:36 +02:00
2018-08-15 10:00:24 +02:00
public List<Emojis> getEmojis() {
return emojis;
}
public void setEmojis(List<Emojis> emojis) {
this.emojis = emojis;
}
2018-11-03 17:29:42 +01:00
2017-09-03 10:36:27 +02:00
public boolean isFollowing() {
return isFollowing;
}
public void setFollowing(boolean following) {
isFollowing = following;
}
public String getFollowers_count_str() {
return followers_count_str;
}
public void setFollowers_count_str(String followers_count_str) {
this.followers_count_str = followers_count_str;
}
public String getFollowing_count_str() {
return following_count_str;
}
public void setFollowing_count_str(String following_count_str) {
this.following_count_str = following_count_str;
}
public String getStatuses_count_str() {
return statuses_count_str;
}
public void setStatuses_count_str(String statuses_count_str) {
this.statuses_count_str = statuses_count_str;
}
/**
* Makes the move to account clickable
* @param context Context
* @return SpannableString
*/
public SpannableString moveToText(final android.content.Context context){
SpannableString spannableString = null;
if( this.getMoved_to_account() != null) {
spannableString = new SpannableString(context.getString(R.string.account_moved_to, this.getAcct(), "@"+this.getMoved_to_account().getAcct()));
int startPositionTar = spannableString.toString().indexOf("@"+this.getMoved_to_account().getAcct());
int endPositionTar = startPositionTar + ("@"+this.getMoved_to_account().getAcct()).length();
2018-12-22 11:43:28 +01:00
final Account idTar = this.getMoved_to_account();
2018-10-07 11:18:52 +02:00
if( endPositionTar <= spannableString.toString().length() && endPositionTar >= startPositionTar)
spannableString.setSpan(new ClickableSpan() {
@Override
2019-01-24 11:49:23 +01:00
public void onClick(@NonNull View textView) {
2018-10-07 11:18:52 +02:00
Intent intent = new Intent(context, ShowAccountActivity.class);
Bundle b = new Bundle();
2018-12-22 11:43:28 +01:00
b.putParcelable("account", idTar);
2018-10-07 11:18:52 +02:00
intent.putExtras(b);
context.startActivity(intent);
}
@Override
2019-01-24 11:49:23 +01:00
public void updateDrawState(@NonNull TextPaint ds) {
2018-10-07 11:18:52 +02:00
super.updateDrawState(ds);
}
},
startPositionTar, endPositionTar,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
return spannableString;
}
2018-12-22 11:43:28 +01:00
public void makeEmojisAccountProfile(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account){
2018-08-15 10:00:24 +02:00
if( ((Activity)context).isFinishing() )
return;
2018-11-01 16:37:49 +01:00
if( fields == null)
fields = new LinkedHashMap<>();
if( fieldsSpan == null)
fieldsSpan = new LinkedHashMap<>();
2018-10-24 18:29:12 +02:00
if( account.getDisplay_name() != null)
displayNameSpan = new SpannableString(account.getDisplay_name());
2019-01-24 11:49:23 +01:00
ArrayList<Account> accountsMentionUnknown = new ArrayList<>();
2018-10-24 18:29:12 +02:00
if( account.getFields() != null && account.getFields().size() > 0) {
Iterator it = account.getFields().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
SpannableString fieldSpan;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
fieldSpan = new SpannableString(Html.fromHtml((String)pair.getValue(), FROM_HTML_MODE_LEGACY));
else
//noinspection deprecation
fieldSpan = new SpannableString(Html.fromHtml((String)pair.getValue()));
fieldsSpan.put(new SpannableString((String)pair.getKey()), fieldSpan);
2019-01-24 11:49:23 +01:00
Pattern aLink = Pattern.compile("(<\\s?a\\s?href=\"https?:\\/\\/([\\da-z\\.-]+\\.[a-z\\.]{2,10})\\/(@[\\/\\w._-]*)\"\\s?[^.]*<\\s?\\/\\s?a\\s?>)");
Matcher matcherALink = aLink.matcher((String)pair.getValue());
while (matcherALink.find()){
String acct = matcherALink.group(3).replace("@","");
String instance = matcherALink.group(2);
Account accountMention = new Account();
accountMention.setAcct(acct);
accountMention.setInstance(instance);
accountsMentionUnknown.add(accountMention);
}
2018-10-24 18:29:12 +02:00
}
account.setFieldsSpan(fieldsSpan);
}
2019-01-24 11:49:23 +01:00
2018-12-31 12:06:50 +01:00
Iterator it = fieldsSpan.entrySet().iterator();
while (it.hasNext()) {
2019-01-24 11:49:23 +01:00
2018-12-31 12:06:50 +01:00
Map.Entry pair = (Map.Entry) it.next();
SpannableString fieldSpan = (SpannableString) pair.getValue();
SpannableString keySpan = (SpannableString) pair.getKey();
2019-01-24 11:49:23 +01:00
2018-12-31 12:06:50 +01:00
Matcher matcher = Helper.xmppPattern.matcher(fieldSpan);
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
while (matcher.find()){
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
for(URLSpan span : urls)
fieldSpan.removeSpan(span);
int matchStart = matcher.start(0);
int matchEnd = matcher.end();
final String url = fieldSpan.toString().substring(matchStart, matchEnd);
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
fieldSpan.setSpan(new ClickableSpan() {
@Override
2019-01-24 11:49:23 +01:00
public void onClick(@NonNull View textView) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
}catch (Exception e){
Toasty.error(context, context.getString(R.string.toast_no_apps), Toast.LENGTH_LONG).show();
}
2018-12-31 12:06:50 +01:00
}
@Override
2019-01-24 11:49:23 +01:00
public void updateDrawState(@NonNull TextPaint ds) {
2018-12-31 12:06:50 +01:00
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (theme == THEME_DARK)
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
else if (theme == THEME_BLACK)
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
else if (theme == THEME_LIGHT)
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
fieldsSpan.put(keySpan, fieldSpan);
}
}
2018-12-31 16:11:44 +01:00
matcher = android.util.Patterns.EMAIL_ADDRESS.matcher(fieldSpan);
while (matcher.find()){
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
for(URLSpan span : urls)
fieldSpan.removeSpan(span);
int matchStart = matcher.start(0);
int matchEnd = matcher.end();
final String email = fieldSpan.toString().substring(matchStart, matchEnd);
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
fieldSpan.setSpan(new ClickableSpan() {
@Override
2019-01-24 11:49:23 +01:00
public void onClick(@NonNull View textView) {
2018-12-31 16:11:44 +01:00
try {
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{email});
context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.send_email)));
}catch (Exception e){
Toasty.error(context, context.getString(R.string.toast_no_apps), Toast.LENGTH_LONG).show();
}
}
@Override
2019-01-24 11:49:23 +01:00
public void updateDrawState(@NonNull TextPaint ds) {
2018-12-31 16:11:44 +01:00
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (theme == THEME_DARK)
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
else if (theme == THEME_BLACK)
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
else if (theme == THEME_LIGHT)
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
fieldsSpan.put(keySpan, fieldSpan);
}
}
2019-01-24 11:49:23 +01:00
matcher = hashtagPattern.matcher(fieldSpan);
while (matcher.find()){
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
for(URLSpan span : urls)
fieldSpan.removeSpan(span);
int matchStart = matcher.start(1);
int matchEnd = matcher.end();
final String tag = fieldSpan.toString().substring(matchStart, matchEnd);
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart)
fieldSpan.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View textView) {
Intent intent = new Intent(context, HashTagActivity.class);
Bundle b = new Bundle();
b.putString("tag", tag.substring(1));
intent.putExtras(b);
context.startActivity(intent);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (theme == THEME_DARK)
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
else if (theme == THEME_BLACK)
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
else if (theme == THEME_LIGHT)
ds.setColor(ContextCompat.getColor(context, R.color.mastodonC4));
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
if( accountsMentionUnknown.size() > 0 ) {
for(Account accountMention: accountsMentionUnknown){
String targetedAccount = "@" + accountMention.getAcct();
if (fieldSpan.toString().toLowerCase().contains(targetedAccount.toLowerCase())) {
//Accounts can be mentioned several times so we have to loop
for(int startPosition = -1 ; (startPosition = fieldSpan.toString().toLowerCase().indexOf(targetedAccount.toLowerCase(), startPosition + 1)) != -1 ; startPosition++){
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
for(URLSpan span : urls)
fieldSpan.removeSpan(span);
int endPosition = startPosition + targetedAccount.length();
if( endPosition <= fieldSpan.toString().length() && endPosition >= startPosition)
fieldSpan.setSpan(new ClickableSpan() {
2019-01-24 11:52:54 +01:00
@Override
public void onClick(@NonNull View textView) {
CrossActions.doCrossProfile(context,accountMention);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (theme == THEME_DARK)
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
else if (theme == THEME_BLACK)
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
else if (theme == THEME_LIGHT)
ds.setColor(ContextCompat.getColor(context, R.color.mastodonC4));
}
},
2019-01-24 11:49:23 +01:00
startPosition, endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
}
2018-12-31 16:11:44 +01:00
}
it = fieldsSpan.entrySet().iterator();
fieldsVerified = account.getFieldsVerified();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
SpannableString fieldSpan = (SpannableString) pair.getValue();
SpannableString keySpan = (SpannableString) pair.getKey();
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
Matcher matcher;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
matcher = Patterns.WEB_URL.matcher(fieldSpan);
else
matcher = Helper.urlPattern.matcher(fieldSpan);
while (matcher.find()){
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
for(URLSpan span : urls)
fieldSpan.removeSpan(span);
int matchStart = matcher.start(0);
int matchEnd = matcher.end();
final String url = fieldSpan.toString().substring(matchStart, matchEnd);
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
fieldSpan.setSpan(new ClickableSpan() {
@Override
2019-01-24 11:49:23 +01:00
public void onClick(@NonNull View textView) {
2018-12-31 16:11:44 +01:00
Helper.openBrowser(context, url);
}
@Override
2019-01-24 11:49:23 +01:00
public void updateDrawState(@NonNull TextPaint ds) {
2018-12-31 16:11:44 +01:00
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (theme == THEME_DARK)
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
else if (theme == THEME_BLACK)
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
else if (theme == THEME_LIGHT)
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
}
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
fieldsSpan.put(keySpan, fieldSpan);
}
}
2018-12-31 12:06:50 +01:00
}
2018-12-31 16:11:44 +01:00
2018-10-24 18:29:12 +02:00
final List<Emojis> emojis = account.getEmojis();
if( emojis != null && emojis.size() > 0 ) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
fields = account.getFields();
try {
Glide.with(context)
.asBitmap()
.load(emoji.getUrl())
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (noteSpan != null && noteSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = noteSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= noteSpan.toString().length() && endPosition >= startPosition)
noteSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition)
displayNameSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
Iterator it = fieldsSpan.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
SpannableString fieldSpan = (SpannableString) pair.getValue();
SpannableString keySpan = (SpannableString) pair.getKey();
if (fieldSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = fieldSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= fieldSpan.toString().length() && endPosition >= startPosition)
fieldSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
fieldsSpan.put((SpannableString) pair.getKey(), fieldSpan);
}else
fieldsSpan.put(keySpan, fieldSpan);
}
i[0]++;
if (i[0] == (emojis.size())) {
if (noteSpan != null)
account.setNoteSpan(noteSpan);
account.setFieldsSpan(fieldsSpan);
if (listener != null)
listener.onRetrieveEmojiAccount(account);
2018-12-23 20:01:19 +01:00
}
}
});
}catch (Exception ignored){}
}
2018-12-31 12:06:50 +01:00
}else {
if (listener != null)
listener.onRetrieveEmojiAccount(account);
2018-12-23 20:01:19 +01:00
}
2018-12-31 12:06:50 +01:00
2018-12-23 20:01:19 +01:00
}
public void makeAccountNameEmoji(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account){
if( ((Activity)context).isFinishing() )
return;
if( account.getDisplay_name() != null)
displayNameSpan = new SpannableString(account.getDisplay_name());
final List<Emojis> emojis = account.getEmojis();
if( emojis != null && emojis.size() > 0 ) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
try {
Glide.with(context)
.asBitmap()
.load(emoji.getUrl())
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition)
displayNameSpan.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
i[0]++;
if (i[0] == (emojis.size())) {
if (listener != null)
listener.onRetrieveEmojiAccount(account);
2018-10-24 18:29:12 +02:00
}
}
});
}catch (Exception ignored){}
}
}
}
2018-11-01 16:37:49 +01:00
2019-01-16 13:47:41 +01:00
2017-05-05 16:36:04 +02:00
}