bug fix, improved connection selector, removed unnecessary database calls

This commit is contained in:
nuclearfog 2023-02-23 21:55:57 +01:00
parent 2483df74c8
commit 5e3de37df2
No known key found for this signature in database
GPG Key ID: 03488A185C476379
36 changed files with 528 additions and 529 deletions

View File

@ -2,6 +2,7 @@ package org.nuclearfog.twidda.backend.api;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.backend.api.mastodon.Mastodon;
@ -16,21 +17,68 @@ import org.nuclearfog.twidda.config.GlobalSettings.OnSettingsChangeListener;
*
* @author nuclearfog
*/
public class ConnectionManager {
public class ConnectionManager implements OnSettingsChangeListener {
private static Connection connection;
private static boolean notifySettingsChange = false;
private static final int IDX_MASTODON = 0;
private static final int IDX_TWITTER1 = 1;
private static final int IDX_TWITTER2 = 2;
private ConnectionManager() {
private static ConnectionManager instance;
private Connection[] connections;
private GlobalSettings settings;
private boolean notifyChanged = false;
/**
*
*/
private ConnectionManager(Context context) {
connections = new Connection[3];
connections[IDX_MASTODON] = new Mastodon(context);
connections[IDX_TWITTER1] = new TwitterV1(context);
connections[IDX_TWITTER2] = new TwitterV2(context);
settings = GlobalSettings.getInstance(context);
settings.addSettingsChangeListener(this);
}
@Override
public void onSettingsChange() {
notifyChanged = true;
}
/**
* get singleton class of a connection
* creates a connection to an online service
*
* @return singleton instance
* @return connection
*/
public static Connection get(Context context) {
return get(context, null);
@NonNull
public static Connection getConnection(Context context) {
return getConnection(context, null);
}
/**
* creates a connection to an online service
*
* @param config configuration to use, null to choose automatically
* @return connection
*/
@NonNull
public static Connection getConnection(Context context, @Nullable Configuration config) {
ConnectionManager manager = ConnectionManager.getInstance(context);
return manager.getConnection(config);
}
/**
* @return singleton instance of this class
*/
@NonNull
public static ConnectionManager getInstance(Context context) {
if (instance == null || instance.notifyChanged) {
instance = new ConnectionManager(context);
}
return instance;
}
/**
@ -39,37 +87,22 @@ public class ConnectionManager {
* @param config Network selection or null to choose automatically
* @return singleton instance
*/
public static Connection get(Context context, @Nullable Configuration config) {
@NonNull
public Connection getConnection(@Nullable Configuration config) {
// create new singleton instance if there is none or if settings change
if (notifySettingsChange || connection == null || config != null) {
notifySettingsChange = false;
GlobalSettings settings = GlobalSettings.getInstance(context);
// select automatically
if (config == null)
config = settings.getLogin().getConfiguration();
switch (config) {
case TWITTER1:
connection = new TwitterV1(context);
break;
case TWITTER2:
connection = new TwitterV2(context);
break;
case MASTODON:
connection = new Mastodon(context);
break;
default:
throw new RuntimeException("no connection selected!");
}
settings.addSettingsChangeListener(new OnSettingsChangeListener() {
@Override
public void onSettingsChange() {
notifySettingsChange = true;
}
});
if (config == null) {
config = instance.settings.getLogin().getConfiguration();
}
switch (config) {
default:
case MASTODON:
return instance.connections[IDX_MASTODON];
case TWITTER1:
return instance.connections[IDX_TWITTER1];
case TWITTER2:
return instance.connections[IDX_TWITTER2];
}
return connection;
}
}

View File

@ -113,7 +113,7 @@ public class TwitterV2 extends TwitterV1 {
@Override
public Poll getPoll(long id) throws ConnectionException {
return null; // todo implement this
throw new TwitterException("not implemented!");
}
/**

View File

@ -13,14 +13,14 @@ import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Executor for tasks running in the bnackground
* Executor implementation used to run tasks asynchronously
*
* @author nuclearfog
*/
public abstract class AsyncExecutor<Parameter, Result> {
/**
* Thread count used to parallelize background tasks
* maximum task count to run in the background
*/
private static final int N_THREAD = 2;
@ -90,7 +90,6 @@ public abstract class AsyncExecutor<Parameter, Result> {
});
}
/**
* This method is called in a background thread
*

View File

@ -30,7 +30,7 @@ public class FilterLoader extends AsyncExecutor<FilterLoader.FilterParam, Filter
*
*/
public FilterLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}
@ -42,7 +42,7 @@ public class FilterLoader extends AsyncExecutor<FilterLoader.FilterParam, Filter
switch (param.mode) {
case FilterParam.RELOAD:
List<Long> ids = connection.getIdBlocklist();
db.setFilterlistUserIds(ids);
db.saveFilterlist(ids);
return new FilterResult(FilterResult.RELOAD, null);
case FilterParam.MUTE:

View File

@ -32,7 +32,7 @@ public class ImageLoader extends AsyncExecutor<ImageLoader.ImageParameter, Image
* @param context Activity context
*/
public ImageLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -40,7 +40,7 @@ public class LinkLoader extends AsyncExecutor<Uri, LinkLoader.LinkResult> {
*
*/
public LinkLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -23,7 +23,7 @@ public class ListAction extends AsyncExecutor<ListAction.ListActionParam, ListAc
*
*/
public ListAction(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -25,30 +25,29 @@ public class ListLoader extends AsyncExecutor<ListLoader.UserlistParam, ListLoad
*
*/
public ListLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}
@NonNull
@Override
protected UserlistResult doInBackground(UserlistParam param) {
UserLists userlists = null;
try {
switch (param.type) {
case UserlistParam.LOAD_USERLISTS:
userlists = connection.getUserlistOwnerships(param.id, param.cursor);
break;
switch (param.mode) {
case UserlistParam.OWNERSHIP:
UserLists userlists = connection.getUserlistOwnerships(param.id, param.cursor);
return new UserlistResult(UserlistResult.OWNERSHIP, userlists, null);
case UserlistParam.LOAD_MEMBERSHIPS:
case UserlistParam.MEMBERSHIP:
userlists = connection.getUserlistMemberships(param.id, param.cursor);
break;
return new UserlistResult(UserlistResult.MEMBERSHIP, userlists, null);
}
} catch (ConnectionException exception) {
return new UserlistResult(null, exception);
return new UserlistResult(UserlistResult.ERROR, null, exception);
} catch (Exception e) {
e.printStackTrace();
}
return new UserlistResult(userlists, null);
return new UserlistResult(UserlistResult.ERROR, null, null);
}
/**
@ -56,14 +55,14 @@ public class ListLoader extends AsyncExecutor<ListLoader.UserlistParam, ListLoad
*/
public static class UserlistParam {
public static final int LOAD_USERLISTS = 1;
public static final int LOAD_MEMBERSHIPS = 2;
public static final int OWNERSHIP = 1;
public static final int MEMBERSHIP = 2;
public final int type;
public final int mode;
public final long id, cursor;
public UserlistParam(int type, long id, long cursor) {
this.type = type;
public UserlistParam(int mode, long id, long cursor) {
this.mode = mode;
this.id = id;
this.cursor = cursor;
}
@ -74,14 +73,20 @@ public class ListLoader extends AsyncExecutor<ListLoader.UserlistParam, ListLoad
*/
public static class UserlistResult {
public static final int ERROR = -1;
public static final int OWNERSHIP = 3;
public static final int MEMBERSHIP = 4;
public final int mode;
@Nullable
public final UserLists userlists;
@Nullable
public final ConnectionException exception;
UserlistResult(@Nullable UserLists userlists, @Nullable ConnectionException exception) {
UserlistResult(int mode, @Nullable UserLists userlists, @Nullable ConnectionException exception) {
this.userlists = userlists;
this.exception = exception;
this.mode = mode;
}
}
}

View File

@ -23,7 +23,7 @@ public class ListManager extends AsyncExecutor<ListManager.ListManagerParam, Lis
*
*/
public ListManager(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}
@ -33,11 +33,11 @@ public class ListManager extends AsyncExecutor<ListManager.ListManagerParam, Lis
protected ListManagerResult doInBackground(ListManagerParam param) {
try {
switch (param.mode) {
case ListManagerParam.ADD_USER:
case ListManagerParam.ADD:
connection.addUserToList(param.id, param.username);
return new ListManagerResult(ListManagerResult.ADD_USER, param.username, null);
case ListManagerParam.DEL_USER:
case ListManagerParam.REMOVE:
connection.removeUserFromList(param.id, param.username);
return new ListManagerResult(ListManagerResult.DEL_USER, param.username, null);
}
@ -54,8 +54,8 @@ public class ListManager extends AsyncExecutor<ListManager.ListManagerParam, Lis
*/
public static class ListManagerParam {
public static final int ADD_USER = 1;
public static final int DEL_USER = 2;
public static final int ADD = 1;
public static final int REMOVE = 2;
public final long id;
public final String username;

View File

@ -26,7 +26,7 @@ public class ListUpdater extends AsyncExecutor<UserListUpdate, ListUpdater.ListU
*
*/
public ListUpdater(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}
@ -34,12 +34,13 @@ public class ListUpdater extends AsyncExecutor<UserListUpdate, ListUpdater.ListU
@Override
protected ListUpdateResult doInBackground(UserListUpdate update) {
try {
UserList result;
if (update.exists())
result = connection.updateUserlist(update);
else
result = connection.createUserlist(update);
return new ListUpdateResult(result, update.exists(), null);
if (update.exists()) {
UserList result = connection.updateUserlist(update);
return new ListUpdateResult(result, true, null);
} else {
UserList result = connection.createUserlist(update);
return new ListUpdateResult(result, false, null);
}
} catch (ConnectionException exception) {
return new ListUpdateResult(null, update.exists(), exception);
} catch (Exception e) {

View File

@ -27,7 +27,7 @@ public class LocationLoader extends AsyncExecutor<Void, LocationLoader.LocationL
*
*/
public LocationLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -25,7 +25,7 @@ public class LoginAction extends AsyncExecutor<LoginAction.LoginParam, LoginActi
private AppDatabase database;
private GlobalSettings settings;
private Connection connection;
private ConnectionManager manager;
/**
*
@ -33,20 +33,14 @@ public class LoginAction extends AsyncExecutor<LoginAction.LoginParam, LoginActi
public LoginAction(Context context) {
database = new AppDatabase(context);
settings = GlobalSettings.getInstance(context);
connection = ConnectionManager.get(context);
}
/**
* setup connection manually
*/
public void setConnection(Context context, Configuration configuration) {
connection = ConnectionManager.get(context, configuration);
manager = ConnectionManager.getInstance(context);
}
@NonNull
@Override
protected LoginResult doInBackground(LoginParam param) {
Connection connection = manager.getConnection(param.configuration);
try {
switch (param.mode) {
case LoginParam.MODE_REQUEST:
@ -56,12 +50,12 @@ public class LoginAction extends AsyncExecutor<LoginAction.LoginParam, LoginActi
database.saveLogin(login);
}
}
String redirectUrl = connection.getAuthorisationLink(param.config);
String redirectUrl = connection.getAuthorisationLink(param.connection);
return new LoginResult(LoginResult.MODE_REQUEST, redirectUrl, null);
case LoginParam.MODE_LOGIN:
// login with pin and access token
Account account = connection.loginApp(param.config, param.code);
Account account = connection.loginApp(param.connection, param.code);
// save new user information
database.saveLogin(account);
return new LoginResult(LoginResult.MODE_LOGIN, null, null);
@ -82,13 +76,15 @@ public class LoginAction extends AsyncExecutor<LoginAction.LoginParam, LoginActi
public static final int MODE_REQUEST = 1;
public static final int MODE_LOGIN = 2;
public final ConnectionConfig config;
public final ConnectionConfig connection;
public final Configuration configuration;
public final String code;
public final int mode;
public LoginParam(int mode, ConnectionConfig config, String code) {
public LoginParam(int mode, Configuration configuration, ConnectionConfig connection, String code) {
this.connection = connection;
this.configuration = configuration;
this.mode = mode;
this.config = config;
this.code = code;
}
}

View File

@ -29,7 +29,7 @@ public class MessageLoader extends AsyncExecutor<MessageLoader.MessageLoaderPara
*/
public MessageLoader(Context context) {
db = new AppDatabase(context);
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -25,7 +25,7 @@ public class MessageUpdater extends AsyncExecutor<MessageUpdate, MessageUpdater.
*
*/
public MessageUpdater(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -28,7 +28,7 @@ public class NotificationLoader extends AsyncExecutor<NotificationLoader.Notific
*
*/
public NotificationLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}
@ -38,15 +38,15 @@ public class NotificationLoader extends AsyncExecutor<NotificationLoader.Notific
protected NotificationResult doInBackground(NotificationParam params) {
List<Notification> result = null;
try {
if (params.minId == 0 && params.maxId == 0) {
if (params.minId == 0L && params.maxId == 0L) {
result = db.getNotifications();
if (result.isEmpty()) {
result = connection.getNotifications(0, 0);
result = connection.getNotifications(0L, 0L);
db.saveNotifications(result);
}
} else {
result = connection.getNotifications(params.minId, params.maxId);
if (params.maxId == 0) {
if (params.maxId == 0L) {
db.saveNotifications(result);
}
}

View File

@ -27,7 +27,7 @@ public class RelationLoader extends AsyncExecutor<RelationLoader.RelationParam,
*
*/
public RelationLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}

View File

@ -27,7 +27,7 @@ public class StatusAction extends AsyncExecutor<StatusAction.StatusParam, Status
*
*/
public StatusAction(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}
@ -48,7 +48,7 @@ public class StatusAction extends AsyncExecutor<StatusAction.StatusParam, Status
status = connection.showStatus(param.id);
if (db.containsStatus(param.id)) {
// update status if there is a database entry
db.updateStatus(status);
db.saveStatus(status);
}
return new StatusResult(StatusResult.ONLINE, status);
@ -59,14 +59,14 @@ public class StatusAction extends AsyncExecutor<StatusAction.StatusParam, Status
case StatusParam.REPOST:
status = connection.repostStatus(param.id);
db.updateStatus(status);
db.saveStatus(status);
if (status.getEmbeddedStatus() != null)
return new StatusResult(StatusResult.REPOST, status.getEmbeddedStatus());
return new StatusResult(StatusResult.REPOST, status);
case StatusParam.UNREPOST:
status = connection.removeRepost(param.id);
db.updateStatus(status);
db.saveStatus(status);
return new StatusResult(StatusResult.UNREPOST, status);
case StatusParam.FAVORITE:

View File

@ -32,7 +32,7 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
*/
public StatusLoader(Context context) {
db = new AppDatabase(context);
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}
@ -47,14 +47,14 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getHomeTimeline();
if (statuses.isEmpty()) {
statuses = connection.getHomeTimeline(request.minId, request.maxId);
statuses = connection.getHomeTimeline(0L, 0L);
db.saveHomeTimeline(statuses);
}
} else if (request.minId > 0L) {
statuses = connection.getHomeTimeline(request.minId, request.maxId);
db.saveHomeTimeline(statuses);
} else if (request.maxId > 1L) {
} else {
statuses = connection.getHomeTimeline(request.minId, request.maxId);
if (request.maxId == 0L) {
db.saveHomeTimeline(statuses);
}
}
break;
@ -62,14 +62,14 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getUserTimeline(request.id);
if (statuses.isEmpty()) {
statuses = connection.getUserTimeline(request.id, 0L, request.maxId);
statuses = connection.getUserTimeline(request.id, 0L, 0L);
db.saveUserTimeline(statuses);
}
} else if (request.minId > 0L) {
statuses = connection.getUserTimeline(request.id, request.minId, request.maxId);
db.saveUserTimeline(statuses);
} else if (request.maxId > 1L) {
} else {
statuses = connection.getUserTimeline(request.id, request.minId, request.maxId);
if (request.maxId == 0L) {
db.saveUserTimeline(statuses);
}
}
break;
@ -77,36 +77,34 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getUserFavorites(request.id);
if (statuses.isEmpty()) {
statuses = connection.getUserFavorits(request.id, 0L, request.maxId);
statuses = connection.getUserFavorits(request.id, 0L, 0L);
db.saveFavoriteTimeline(statuses, request.id);
}
} else if (request.minId > 0L) {
} else {
statuses = connection.getUserFavorits(request.id, 0L, request.maxId);
db.saveFavoriteTimeline(statuses, request.id);
position = CLEAR_LIST; // set flag to clear previous data
} else if (request.maxId > 1L) {
statuses = connection.getUserFavorits(request.id, request.minId, request.maxId);
if (request.maxId == 0L) {
db.saveFavoriteTimeline(statuses, request.id);
position = CLEAR_LIST; // set flag to clear previous data
}
}
break;
case StatusParameter.BOOKMARKS:
if (request.id > 0L) {
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getUserBookmarks(request.id);
if (statuses.isEmpty()) {
statuses = connection.getUserBookmarks(0L, request.maxId);
db.saveBookmarkTimeline(statuses, request.id);
}
} else if (request.minId > 0L) {
statuses = connection.getUserBookmarks(request.minId, request.maxId);
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getUserBookmarks(request.id);
if (statuses.isEmpty()) {
statuses = connection.getUserBookmarks(0L, 0L);
db.saveBookmarkTimeline(statuses, request.id);
}
} else {
statuses = connection.getUserBookmarks(request.minId, request.maxId);
if (request.maxId == 0L) {
db.saveBookmarkTimeline(statuses, request.id);
} else if (request.maxId > 1L) {
statuses = connection.getUserBookmarks(request.minId, request.maxId);
}
}
break;
case StatusParameter.REPLIES_OFFLINE:
case StatusParameter.REPLIES_LOCAL:
statuses = db.getReplies(request.id);
break;
@ -114,18 +112,16 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
if (request.minId == 0L && request.maxId == 0L) {
statuses = db.getReplies(request.id);
if (statuses.isEmpty()) {
statuses = connection.getStatusReplies(request.id, request.minId, request.maxId, request.search);
if (!statuses.isEmpty() && db.containsStatus(request.id)) {
statuses = connection.getStatusReplies(request.id, 0L, 0L, request.search);
if (db.containsStatus(request.id)) {
db.saveReplyTimeline(statuses);
}
}
} else if (request.minId > 0L) {
} else {
statuses = connection.getStatusReplies(request.id, request.minId, request.maxId, request.search);
if (!statuses.isEmpty() && db.containsStatus(request.id)) {
if (request.maxId == 0L && db.containsStatus(request.id)) {
db.saveReplyTimeline(statuses);
}
} else if (request.maxId > 1L) {
statuses = connection.getStatusReplies(request.id, request.minId, request.maxId, request.search);
}
break;
@ -158,7 +154,7 @@ public class StatusLoader extends AsyncExecutor<StatusLoader.StatusParameter, St
public static final int USER = 2;
public static final int FAVORIT = 3;
public static final int REPLIES = 4;
public static final int REPLIES_OFFLINE = 5;
public static final int REPLIES_LOCAL = 5;
public static final int SEARCH = 6;
public static final int USERLIST = 7;
public static final int PUBLIC = 8;

View File

@ -26,7 +26,7 @@ public class StatusUpdater extends AsyncExecutor<StatusUpdate, StatusUpdater.Sta
*
*/
public StatusUpdater(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -33,7 +33,7 @@ public class TrendLoader extends AsyncExecutor<TrendLoader.TrendParameter, Trend
*
*/
public TrendLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}

View File

@ -25,7 +25,7 @@ public class UserLoader extends AsyncExecutor<UserLoader.UserParam, UserLoader.U
*
*/
public UserLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
db = new AppDatabase(context);
}

View File

@ -29,7 +29,7 @@ public class UserUpdater extends AsyncExecutor<ProfileUpdate, UserUpdater.UserUp
*/
public UserUpdater(Context context) {
db = new AppDatabase(context);
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -25,7 +25,7 @@ public class UsersLoader extends AsyncExecutor<UsersLoader.UserParam, UsersLoade
*
*/
public UsersLoader(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -25,7 +25,7 @@ public class VoteUpdater extends AsyncExecutor<VoteUpdater.VoteParam, VoteUpdate
*
*/
public VoteUpdater(Context context) {
connection = ConnectionManager.get(context);
connection = ConnectionManager.getConnection(context);
}

View File

@ -12,15 +12,28 @@ public class UserListUpdate {
/**
* this ID indicates that the list isn't created yet
*/
public static final long NEW_LIST = -1;
private static final long NEW_LIST = -1;
private long listId;
private String title;
private String description;
private boolean isPublic;
/**
* Constructor used for newly created userlist
*
* @param title Title of the list
* @param description short description of the list
* @param isPublic true if list should be public
*/
public UserListUpdate(String title, String description, boolean isPublic) {
this(title, description, isPublic, NEW_LIST);
}
/**
* Constructor used to update existing userlist
*
* @param title Title of the list
* @param description short description of the list
* @param isPublic true if list should be public

View File

@ -22,12 +22,12 @@ public enum Configuration {
/**
* configurations for Mastodon
*/
MASTODON(Account.API_MASTODON),
MASTODON(Account.API_MASTODON);
/**
* dummy configuration
* fallback configuration to use when there is no network selected
*/
NONE(0);
public static final Configuration FALLBACK_CONFIG = MASTODON;
private final int accountType;
private final boolean userlistExtended;

View File

@ -1017,7 +1017,7 @@ public class GlobalSettings {
String consumerSecret = settings.getString(CONSUMER_SECRET, "");
String bearerToken = settings.getString(BEARER_TOKEN, "");
String hostname = settings.getString(HOSTNAME, TWITTER_HOST);
int apiId = settings.getInt(CURRENT_API, Account.API_NONE);
int apiId = settings.getInt(CURRENT_API, 0);
long userId = settings.getLong(CURRENT_ID, 0);
if ((apiId == Account.API_TWITTER_1 || apiId == Account.API_TWITTER_2) && twitterAlt)
hostname = TWITTER_ALT_HOST;

View File

@ -46,10 +46,6 @@ public class ConfigAccount implements Account {
case MASTODON:
type = API_MASTODON;
break;
default:
type = API_NONE;
break;
}
}
@ -137,7 +133,7 @@ public class ConfigAccount implements Account {
return Configuration.MASTODON;
default:
return Configuration.NONE;
return Configuration.FALLBACK_CONFIG;
}
}

View File

@ -295,11 +295,6 @@ public class AppDatabase {
*/
private static final String NOTIFICATION_SELECT = NotificationTable.NAME + "." + NotificationTable.ITEM + "=?";
/**
* select user from user table matching user ID
*/
private static final String USER_SELECT = UserTable.NAME + "." + UserTable.ID + "=?";
/**
* selection to get status flag register
*/
@ -383,39 +378,32 @@ public class AppDatabase {
settings = GlobalSettings.getInstance(context);
}
/**
* Store user information
*
* @param user Twitter user
*/
public void saveUser(User user) {
SQLiteDatabase db = getDbWrite();
saveUser(user, db, CONFLICT_REPLACE);
commit(db);
}
/**
* save home timeline
*
* @param home status from home timeline
* @param statuses status from home timeline
*/
public void saveHomeTimeline(List<Status> home) {
SQLiteDatabase db = getDbWrite();
for (Status status : home)
saveStatus(status, db, HOME_TIMELINE_MASK);
commit(db);
public void saveHomeTimeline(List<Status> statuses) {
if (!statuses.isEmpty()) {
SQLiteDatabase db = getDbWrite();
for (Status status : statuses)
saveStatus(status, db, HOME_TIMELINE_MASK);
commit(db);
}
}
/**
* save user timeline
*
* @param stats user timeline
* @param statuses user timeline
*/
public void saveUserTimeline(List<Status> stats) {
SQLiteDatabase db = getDbWrite();
for (Status status : stats)
saveStatus(status, db, USER_TIMELINE_MASK);
commit(db);
public void saveUserTimeline(List<Status> statuses) {
if (!statuses.isEmpty()) {
SQLiteDatabase db = getDbWrite();
for (Status status : statuses)
saveStatus(status, db, USER_TIMELINE_MASK);
commit(db);
}
}
/**
@ -429,10 +417,12 @@ public class AppDatabase {
// delete old favorits
String[] delArgs = {Long.toString(ownerId)};
db.delete(FavoriteTable.NAME, FAVORITE_SELECT_OWNER, delArgs);
// save new favorits
for (Status status : statuses) {
saveStatus(status, db, 0);
saveFavorite(status.getId(), ownerId, db);
if (!statuses.isEmpty()) {
for (Status status : statuses) {
saveStatus(status, db, 0);
saveFavorite(status.getId(), ownerId, db);
}
}
commit(db);
}
@ -448,10 +438,12 @@ public class AppDatabase {
// delete old favorits
String[] delArgs = {Long.toString(ownerId)};
db.delete(BookmarkTable.NAME, BOOKMARK_SELECT_OWNER, delArgs);
// save new bookmarks
for (Status status : statuses) {
saveStatus(status, db, 0);
saveBookmark(status.getId(), ownerId, db);
if (!statuses.isEmpty()) {
for (Status status : statuses) {
saveStatus(status, db, 0);
saveBookmark(status.getId(), ownerId, db);
}
}
commit(db);
}
@ -459,12 +451,75 @@ public class AppDatabase {
/**
* store replies of a status
*
* @param replies status replies
* @param statuses status replies
*/
public void saveReplyTimeline(List<Status> replies) {
public void saveReplyTimeline(List<Status> statuses) {
if (!statuses.isEmpty()) {
SQLiteDatabase db = getDbWrite();
for (Status status : statuses)
saveStatus(status, db, STATUS_REPLY_MASK);
commit(db);
}
}
/**
* save notifications to database
*/
public void saveNotifications(List<Notification> notifications) {
if (!notifications.isEmpty()) {
SQLiteDatabase db = getDbWrite();
for (Notification notification : notifications) {
ContentValues column = new ContentValues();
column.put(NotificationTable.ID, notification.getId());
column.put(NotificationTable.TIME, notification.getTimestamp());
column.put(NotificationTable.TYPE, notification.getType());
column.put(NotificationTable.OWNER, settings.getLogin().getId());
column.put(NotificationTable.USER, notification.getUser().getId());
saveUser(notification.getUser(), db, CONFLICT_IGNORE);
// add status
if (notification.getStatus() != null) {
saveStatus(notification.getStatus(), db, NOTIFICATION_MASK);
column.put(NotificationTable.ITEM, notification.getStatus().getId());
}
db.insertWithOnConflict(NotificationTable.NAME, null, column, CONFLICT_REPLACE);
}
commit(db);
}
}
/**
* store direct messages
*
* @param messages list of direct messages
*/
public void saveMessages(List<Message> messages) {
if (!messages.isEmpty()) {
SQLiteDatabase db = getDbWrite();
for (Message message : messages)
saveMessages(message, db);
commit(db);
}
}
/**
* create a new filterlist containing user IDs
*
* @param ids list of user IDs
*/
public void saveFilterlist(List<Long> ids) {
long homeId = settings.getLogin().getId();
String[] args = {Long.toString(homeId)};
SQLiteDatabase db = getDbWrite();
for (Status status : replies)
saveStatus(status, db, STATUS_REPLY_MASK);
db.delete(UserExcludeTable.NAME, LIST_SELECT, args);
if (!ids.isEmpty()) {
for (long id : ids) {
ContentValues column = new ContentValues(2);
column.put(UserExcludeTable.ID, id);
column.put(UserExcludeTable.OWNER, homeId);
db.insertWithOnConflict(UserExcludeTable.NAME, null, column, SQLiteDatabase.CONFLICT_IGNORE);
}
}
commit(db);
}
@ -478,12 +533,12 @@ public class AppDatabase {
SQLiteDatabase db = getDbWrite();
db.delete(TrendTable.NAME, TREND_SELECT, args);
for (Trend trend : trends) {
ContentValues trendColumn = new ContentValues(4);
trendColumn.put(TrendTable.ID, trend.getLocationId());
trendColumn.put(TrendTable.VOL, trend.getPopularity());
trendColumn.put(TrendTable.TREND, trend.getName());
trendColumn.put(TrendTable.INDEX, trend.getRank());
db.insert(TrendTable.NAME, null, trendColumn);
ContentValues column = new ContentValues(4);
column.put(TrendTable.ID, trend.getLocationId());
column.put(TrendTable.VOL, trend.getPopularity());
column.put(TrendTable.TREND, trend.getName());
column.put(TrendTable.INDEX, trend.getRank());
db.insert(TrendTable.NAME, null, column);
}
commit(db);
}
@ -516,85 +571,30 @@ public class AppDatabase {
commit(db);
}
/**
* save notifications to database
*/
public void saveNotifications(List<Notification> notifications) {
SQLiteDatabase db = getDbWrite();
for (Notification notification : notifications) {
ContentValues column = new ContentValues();
column.put(NotificationTable.ID, notification.getId());
column.put(NotificationTable.TIME, notification.getTimestamp());
column.put(NotificationTable.TYPE, notification.getType());
column.put(NotificationTable.OWNER, settings.getLogin().getId());
column.put(NotificationTable.USER, notification.getUser().getId());
saveUser(notification.getUser(), db, CONFLICT_IGNORE);
// add status
if (notification.getStatus() != null) {
saveStatus(notification.getStatus(), db, NOTIFICATION_MASK);
column.put(NotificationTable.ITEM, notification.getStatus().getId());
}
db.insertWithOnConflict(NotificationTable.NAME, null, column, CONFLICT_REPLACE);
}
commit(db);
}
/**
* store direct messages
*
* @param messages list of direct messages
*/
public void saveMessages(List<Message> messages) {
SQLiteDatabase db = getDbWrite();
for (Message message : messages)
saveMessages(message, db);
commit(db);
}
/**
* save user login
*
* @param account login information
*/
public void saveLogin(Account account) {
ContentValues values = new ContentValues(9);
values.put(AccountTable.ID, account.getId());
values.put(AccountTable.DATE, account.getTimestamp());
values.put(AccountTable.HOSTNAME, account.getHostname());
values.put(AccountTable.CLIENT_ID, account.getConsumerToken());
values.put(AccountTable.CLIENT_SECRET, account.getConsumerSecret());
values.put(AccountTable.API, account.getConfiguration().getAccountType());
values.put(AccountTable.ACCESS_TOKEN, account.getOauthToken());
values.put(AccountTable.TOKEN_SECRET, account.getOauthSecret());
values.put(AccountTable.BEARER, account.getBearerToken());
ContentValues column = new ContentValues(9);
column.put(AccountTable.ID, account.getId());
column.put(AccountTable.DATE, account.getTimestamp());
column.put(AccountTable.HOSTNAME, account.getHostname());
column.put(AccountTable.CLIENT_ID, account.getConsumerToken());
column.put(AccountTable.CLIENT_SECRET, account.getConsumerSecret());
column.put(AccountTable.API, account.getConfiguration().getAccountType());
column.put(AccountTable.ACCESS_TOKEN, account.getOauthToken());
column.put(AccountTable.TOKEN_SECRET, account.getOauthSecret());
column.put(AccountTable.BEARER, account.getBearerToken());
SQLiteDatabase db = getDbWrite();
db.insertWithOnConflict(AccountTable.NAME, "", values, CONFLICT_REPLACE);
db.insertWithOnConflict(AccountTable.NAME, "", column, CONFLICT_REPLACE);
if (account.getUser() != null) {
saveUser(account.getUser(), db, CONFLICT_IGNORE);
}
commit(db);
}
/**
* create a new filterlist containing user IDs
*
* @param ids list of user IDs
*/
public void setFilterlistUserIds(List<Long> ids) {
long homeId = settings.getLogin().getId();
String[] args = {Long.toString(homeId)};
SQLiteDatabase db = getDbWrite();
db.delete(UserExcludeTable.NAME, LIST_SELECT, args);
for (long id : ids) {
ContentValues column = new ContentValues(2);
column.put(UserExcludeTable.ID, id);
column.put(UserExcludeTable.OWNER, homeId);
db.insertWithOnConflict(UserExcludeTable.NAME, null, column, SQLiteDatabase.CONFLICT_IGNORE);
}
commit(db);
}
/**
* add user to the exclude database
*
@ -668,6 +668,127 @@ public class AppDatabase {
return getStatuses(cursor, db);
}
/**
* get reply timeline
*
* @param id status ID
* @return status reply timeline
*/
public List<Status> getReplies(long id) {
String homeStr = Long.toString(settings.getLogin().getId());
String[] args = {Long.toString(id), homeStr, homeStr, Integer.toString(settings.getListSize())};
SQLiteDatabase db = getDbRead();
Cursor cursor = db.rawQuery(REPLY_QUERY, args);
return getStatuses(cursor, db);
}
/**
* get notifiactions
*
* @return notification lsit
*/
public List<Notification> getNotifications() {
Account login = settings.getLogin();
String[] args = {Long.toString(login.getId()), Integer.toString(settings.getListSize())};
SQLiteDatabase db = getDbRead();
List<Notification> result = new LinkedList<>();
Cursor cursor = db.rawQuery(NOTIFICATION_QUERY, args);
if (cursor.moveToFirst()) {
do {
DatabaseNotification notification = new DatabaseNotification(cursor, login);
switch (notification.getType()) {
case Notification.TYPE_FAVORITE:
case Notification.TYPE_REPOST:
case Notification.TYPE_MENTION:
case Notification.TYPE_POLL:
case Notification.TYPE_STATUS:
case Notification.TYPE_UPDATE:
Status status = getStatus(notification.getItemId());
notification.addStatus(status);
break;
}
result.add(notification);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
/**
* Load trend List
*
* @return list of trends
*/
public List<Trend> getTrends() {
String[] args = {Long.toString(settings.getTrendLocation().getId())};
SQLiteDatabase db = getDbRead();
Cursor cursor = db.query(TrendTable.NAME, DatabaseTrend.COLUMNS, TREND_SELECT, args, null, null, null);
List<Trend> trends = new LinkedList<>();
if (cursor.moveToFirst()) {
do {
trends.add(new DatabaseTrend(cursor));
} while (cursor.moveToNext());
}
cursor.close();
Collections.sort(trends);
return trends;
}
/**
* load direct messages
*
* @return list of direct messages
*/
public Messages getMessages() {
Account login = settings.getLogin();
String homeIdStr = Long.toString(login.getId());
String[] args = {homeIdStr, homeIdStr, Integer.toString(settings.getListSize())};
Messages result = new Messages(null, null);
SQLiteDatabase db = getDbRead();
Cursor cursor = db.rawQuery(MESSAGE_QUERY, args);
if (cursor.moveToFirst()) {
do {
DatabaseMessage item = new DatabaseMessage(cursor, login);
result.add(item);
if (item.getMediaKeys().length > 0) {
List<Media> medias = new LinkedList<>();
for (String key : item.getMediaKeys()) {
Media media = getMedia(db, key);
if (media != null) {
medias.add(media);
}
}
item.addMedia(medias.toArray(new Media[0]));
}
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
/**
* get all user logins
*
* @return list of all logins
*/
public List<Account> getLogins() {
ArrayList<Account> result = new ArrayList<>();
SQLiteDatabase db = getDbRead();
Cursor cursor = db.query(AccountTable.NAME, DatabaseAccount.COLUMNS, null, null, null, null, SORT_BY_CREATION);
if (cursor.moveToFirst()) {
result.ensureCapacity(cursor.getCount());
do {
DatabaseAccount account = new DatabaseAccount(cursor);
account.addUser(getUser(account.getId(), account));
result.add(account);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
/**
* get user information
*
@ -719,50 +840,14 @@ public class AppDatabase {
}
/**
* get reply timeline
* Store user information
*
* @param id status ID
* @return status reply timeline
* @param user Twitter user
*/
public List<Status> getReplies(long id) {
String homeStr = Long.toString(settings.getLogin().getId());
String[] args = {Long.toString(id), homeStr, homeStr, Integer.toString(settings.getListSize())};
SQLiteDatabase db = getDbRead();
Cursor cursor = db.rawQuery(REPLY_QUERY, args);
return getStatuses(cursor, db);
}
/**
* get notifiactions
*
* @return notification lsit
*/
public List<Notification> getNotifications() {
Account login = settings.getLogin();
String[] args = {Long.toString(login.getId()), Integer.toString(settings.getListSize())};
SQLiteDatabase db = getDbRead();
List<Notification> result = new LinkedList<>();
Cursor cursor = db.rawQuery(NOTIFICATION_QUERY, args);
if (cursor.moveToFirst()) {
do {
DatabaseNotification notification = new DatabaseNotification(cursor, login);
switch (notification.getType()) {
case Notification.TYPE_FAVORITE:
case Notification.TYPE_REPOST:
case Notification.TYPE_MENTION:
case Notification.TYPE_POLL:
case Notification.TYPE_STATUS:
case Notification.TYPE_UPDATE:
Status status = getStatus(notification.getItemId());
notification.addStatus(status);
break;
}
result.add(notification);
} while (cursor.moveToNext());
}
cursor.close();
return result;
public void saveUser(User user) {
SQLiteDatabase db = getDbWrite();
saveUser(user, db, CONFLICT_REPLACE);
commit(db);
}
/**
@ -770,11 +855,11 @@ public class AppDatabase {
*
* @param status status to update
*/
public void updateStatus(Status status) {
public void saveStatus(Status status) {
SQLiteDatabase db = getDbWrite();
updateStatus(status, db);
saveStatus(status, db, CONFLICT_REPLACE);
if (status.getEmbeddedStatus() != null)
updateStatus(status.getEmbeddedStatus(), db);
saveStatus(status.getEmbeddedStatus(), db, CONFLICT_REPLACE);
commit(db);
}
@ -794,9 +879,9 @@ public class AppDatabase {
} else {
flags &= ~HIDDEN_MASK;
}
ContentValues values = new ContentValues(3);
values.put(StatusRegisterTable.REGISTER, flags);
db.update(StatusRegisterTable.NAME, values, STATUS_REG_SELECT, args);
ContentValues column = new ContentValues(1);
column.put(StatusRegisterTable.REGISTER, flags);
db.update(StatusRegisterTable.NAME, column, STATUS_REG_SELECT, args);
commit(db);
}
@ -884,58 +969,6 @@ public class AppDatabase {
commit(db);
}
/**
* Load trend List
*
* @return list of trends
*/
public List<Trend> getTrends() {
String[] args = {Long.toString(settings.getTrendLocation().getId())};
SQLiteDatabase db = getDbRead();
Cursor cursor = db.query(TrendTable.NAME, DatabaseTrend.COLUMNS, TREND_SELECT, args, null, null, null);
List<Trend> trends = new LinkedList<>();
if (cursor.moveToFirst()) {
do {
trends.add(new DatabaseTrend(cursor));
} while (cursor.moveToNext());
}
cursor.close();
Collections.sort(trends);
return trends;
}
/**
* load direct messages
*
* @return list of direct messages
*/
public Messages getMessages() {
Account login = settings.getLogin();
String homeIdStr = Long.toString(login.getId());
String[] args = {homeIdStr, homeIdStr, Integer.toString(settings.getListSize())};
Messages result = new Messages(null, null);
SQLiteDatabase db = getDbRead();
Cursor cursor = db.rawQuery(MESSAGE_QUERY, args);
if (cursor.moveToFirst()) {
do {
DatabaseMessage item = new DatabaseMessage(cursor, login);
result.add(item);
if (item.getMediaKeys().length > 0) {
List<Media> medias = new LinkedList<>();
for (String key : item.getMediaKeys()) {
Media media = getMedia(db, key);
if (media != null) {
medias.add(media);
}
}
item.addMedia(medias.toArray(new Media[0]));
}
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
/**
* return the current filterlist containing user IDs
*
@ -1017,28 +1050,6 @@ public class AppDatabase {
commit(db);
}
/**
* get all user logins
*
* @return list of all logins
*/
public List<Account> getLogins() {
ArrayList<Account> result = new ArrayList<>();
SQLiteDatabase db = getDbRead();
Cursor cursor = db.query(AccountTable.NAME, DatabaseAccount.COLUMNS, null, null, null, null, SORT_BY_CREATION);
if (cursor.moveToFirst()) {
result.ensureCapacity(cursor.getCount());
do {
DatabaseAccount account = new DatabaseAccount(cursor);
account.addUser(getUser(account.getId(), account));
result.add(account);
} while (cursor.moveToNext());
}
cursor.close();
return result;
}
/**
* get status information from database
*
@ -1222,22 +1233,22 @@ public class AppDatabase {
} else {
flags &= ~DEFAULT_IMAGE_MASK;
}
ContentValues userColumn = new ContentValues(13);
userColumn.put(UserTable.ID, user.getId());
userColumn.put(UserTable.USERNAME, user.getUsername());
userColumn.put(UserTable.SCREENNAME, user.getScreenname());
userColumn.put(UserTable.IMAGE, user.getOriginalProfileImageUrl());
userColumn.put(UserTable.DESCRIPTION, user.getDescription());
userColumn.put(UserTable.LINK, user.getProfileUrl());
userColumn.put(UserTable.LOCATION, user.getLocation());
userColumn.put(UserTable.BANNER, user.getOriginalBannerImageUrl());
userColumn.put(UserTable.SINCE, user.getTimestamp());
userColumn.put(UserTable.FRIENDS, user.getFollowing());
userColumn.put(UserTable.FOLLOWER, user.getFollower());
userColumn.put(UserTable.STATUSES, user.getStatusCount());
userColumn.put(UserTable.FAVORITS, user.getFavoriteCount());
ContentValues column = new ContentValues(13);
column.put(UserTable.ID, user.getId());
column.put(UserTable.USERNAME, user.getUsername());
column.put(UserTable.SCREENNAME, user.getScreenname());
column.put(UserTable.IMAGE, user.getOriginalProfileImageUrl());
column.put(UserTable.DESCRIPTION, user.getDescription());
column.put(UserTable.LINK, user.getProfileUrl());
column.put(UserTable.LOCATION, user.getLocation());
column.put(UserTable.BANNER, user.getOriginalBannerImageUrl());
column.put(UserTable.SINCE, user.getTimestamp());
column.put(UserTable.FRIENDS, user.getFollowing());
column.put(UserTable.FOLLOWER, user.getFollower());
column.put(UserTable.STATUSES, user.getStatusCount());
column.put(UserTable.FAVORITS, user.getFavoriteCount());
db.insertWithOnConflict(UserTable.NAME, "", userColumn, mode);
db.insertWithOnConflict(UserTable.NAME, "", column, mode);
saveUserFlags(db, user.getId(), flags);
}
@ -1277,26 +1288,26 @@ public class AppDatabase {
} else {
flags &= ~BOOKMARK_MASK;
}
ContentValues statusUpdate = new ContentValues(18);
statusUpdate.put(StatusTable.ID, status.getId());
statusUpdate.put(StatusTable.USER, user.getId());
statusUpdate.put(StatusTable.TIME, status.getTimestamp());
statusUpdate.put(StatusTable.TEXT, status.getText());
statusUpdate.put(StatusTable.EMBEDDED, rtId);
statusUpdate.put(StatusTable.SOURCE, status.getSource());
statusUpdate.put(StatusTable.URL, status.getUrl());
statusUpdate.put(StatusTable.REPLYSTATUS, status.getRepliedStatusId());
statusUpdate.put(StatusTable.REPOST, status.getRepostCount());
statusUpdate.put(StatusTable.FAVORITE, status.getFavoriteCount());
statusUpdate.put(StatusTable.REPLYUSER, status.getRepliedUserId());
statusUpdate.put(StatusTable.REPLYUSER, status.getRepliedUserId());
statusUpdate.put(StatusTable.REPLYNAME, status.getReplyName());
statusUpdate.put(StatusTable.CONVERSATION, status.getConversationId());
ContentValues column = new ContentValues(17);
column.put(StatusTable.ID, status.getId());
column.put(StatusTable.USER, user.getId());
column.put(StatusTable.TIME, status.getTimestamp());
column.put(StatusTable.TEXT, status.getText());
column.put(StatusTable.EMBEDDED, rtId);
column.put(StatusTable.SOURCE, status.getSource());
column.put(StatusTable.URL, status.getUrl());
column.put(StatusTable.REPLYSTATUS, status.getRepliedStatusId());
column.put(StatusTable.REPOST, status.getRepostCount());
column.put(StatusTable.FAVORITE, status.getFavoriteCount());
column.put(StatusTable.REPLYUSER, status.getRepliedUserId());
column.put(StatusTable.REPLYUSER, status.getRepliedUserId());
column.put(StatusTable.REPLYNAME, status.getReplyName());
column.put(StatusTable.CONVERSATION, status.getConversationId());
if (status.getLocation() != null && status.getLocation().getId() != 0L) {
statusUpdate.put(StatusTable.LOCATION, status.getLocation().getId());
column.put(StatusTable.LOCATION, status.getLocation().getId());
saveLocation(status.getLocation(), db);
} else {
statusUpdate.put(StatusTable.LOCATION, 0L);
column.put(StatusTable.LOCATION, 0L);
}
if (status.getMedia().length > 0) {
StringBuilder buf = new StringBuilder();
@ -1305,7 +1316,7 @@ public class AppDatabase {
buf.append(media.getKey()).append(';');
}
String mediaKeys = buf.deleteCharAt(buf.length() - 1).toString();
statusUpdate.put(StatusTable.MEDIA, mediaKeys);
column.put(StatusTable.MEDIA, mediaKeys);
}
if (status.getEmojis().length > 0) {
StringBuilder buf = new StringBuilder();
@ -1314,9 +1325,9 @@ public class AppDatabase {
buf.append(emoji.getCode()).append(';');
}
String emojiKeys = buf.deleteCharAt(buf.length() - 1).toString();
statusUpdate.put(StatusTable.EMOJI, emojiKeys);
column.put(StatusTable.EMOJI, emojiKeys);
}
db.insertWithOnConflict(StatusTable.NAME, "", statusUpdate, CONFLICT_REPLACE);
db.insertWithOnConflict(StatusTable.NAME, "", column, CONFLICT_REPLACE);
saveUser(user, db, CONFLICT_IGNORE);
saveStatusFlags(db, status, flags);
}
@ -1361,13 +1372,13 @@ public class AppDatabase {
* @param db database write instance
*/
private void saveLocation(Location location, SQLiteDatabase db) {
ContentValues locationColumn = new ContentValues(5);
locationColumn.put(LocationTable.ID, location.getId());
locationColumn.put(LocationTable.FULLNAME, location.getFullName());
locationColumn.put(LocationTable.COORDINATES, location.getCoordinates());
locationColumn.put(LocationTable.COUNTRY, location.getCountry());
locationColumn.put(LocationTable.PLACE, location.getPlace());
db.insertWithOnConflict(LocationTable.NAME, "", locationColumn, CONFLICT_IGNORE);
ContentValues column = new ContentValues(5);
column.put(LocationTable.ID, location.getId());
column.put(LocationTable.FULLNAME, location.getFullName());
column.put(LocationTable.COORDINATES, location.getCoordinates());
column.put(LocationTable.COUNTRY, location.getCountry());
column.put(LocationTable.PLACE, location.getPlace());
db.insertWithOnConflict(LocationTable.NAME, "", column, CONFLICT_IGNORE);
}
/**
@ -1380,16 +1391,16 @@ public class AppDatabase {
private void saveStatusFlags(SQLiteDatabase db, Status status, int flags) {
String[] args = {Long.toString(status.getId()), Long.toString(settings.getLogin().getId())};
ContentValues values = new ContentValues(4);
values.put(StatusRegisterTable.REGISTER, flags);
values.put(StatusRegisterTable.REPOST_ID, status.getRepostId());
values.put(StatusRegisterTable.ID, status.getId());
values.put(StatusRegisterTable.OWNER, settings.getLogin().getId());
ContentValues column = new ContentValues(4);
column.put(StatusRegisterTable.REGISTER, flags);
column.put(StatusRegisterTable.REPOST_ID, status.getRepostId());
column.put(StatusRegisterTable.ID, status.getId());
column.put(StatusRegisterTable.OWNER, settings.getLogin().getId());
int count = db.update(StatusRegisterTable.NAME, values, STATUS_REG_SELECT, args);
int count = db.update(StatusRegisterTable.NAME, column, STATUS_REG_SELECT, args);
if (count == 0) {
// create new entry if there isn't one
db.insert(StatusRegisterTable.NAME, null, values);
db.insert(StatusRegisterTable.NAME, null, column);
}
}
@ -1403,15 +1414,15 @@ public class AppDatabase {
private void saveUserFlags(SQLiteDatabase db, long id, int flags) {
String[] args = {Long.toString(id), Long.toString(settings.getLogin().getId())};
ContentValues values = new ContentValues(3);
values.put(UserRegisterTable.ID, id);
values.put(UserRegisterTable.OWNER, settings.getLogin().getId());
values.put(UserRegisterTable.REGISTER, flags);
ContentValues column = new ContentValues(3);
column.put(UserRegisterTable.ID, id);
column.put(UserRegisterTable.OWNER, settings.getLogin().getId());
column.put(UserRegisterTable.REGISTER, flags);
int cnt = db.update(UserRegisterTable.NAME, values, USER_REG_SELECT, args);
int cnt = db.update(UserRegisterTable.NAME, column, USER_REG_SELECT, args);
if (cnt == 0) {
// create new entry if there isn't an entry
db.insert(UserRegisterTable.NAME, null, values);
db.insert(UserRegisterTable.NAME, null, column);
}
}
@ -1451,77 +1462,25 @@ public class AppDatabase {
*/
private void saveMessages(Message message, SQLiteDatabase db) {
// store message information
ContentValues messageColumn = new ContentValues(6);
messageColumn.put(MessageTable.ID, message.getId());
messageColumn.put(MessageTable.TIME, message.getTimestamp());
messageColumn.put(MessageTable.FROM, message.getSender().getId());
messageColumn.put(MessageTable.TO, message.getReceiverId());
messageColumn.put(MessageTable.MESSAGE, message.getText());
ContentValues column = new ContentValues(6);
column.put(MessageTable.ID, message.getId());
column.put(MessageTable.TIME, message.getTimestamp());
column.put(MessageTable.FROM, message.getSender().getId());
column.put(MessageTable.TO, message.getReceiverId());
column.put(MessageTable.MESSAGE, message.getText());
if (message.getMedia().length > 0) {
StringBuilder keyBuf = new StringBuilder();
for (Media media : message.getMedia())
keyBuf.append(media.getKey()).append(';');
keyBuf.deleteCharAt(keyBuf.length() - 1);
messageColumn.put(MessageTable.MEDIA, keyBuf.toString());
column.put(MessageTable.MEDIA, keyBuf.toString());
saveMedia(message.getMedia(), db);
}
db.insertWithOnConflict(MessageTable.NAME, "", messageColumn, CONFLICT_IGNORE);
db.insertWithOnConflict(MessageTable.NAME, "", column, CONFLICT_IGNORE);
// store user information
saveUser(message.getSender(), db, CONFLICT_IGNORE);
}
/**
* updates existing status
*
* @param status update of the status
* @param db database instance
*/
private void updateStatus(Status status, SQLiteDatabase db) {
String[] statusIdArg = {Long.toString(status.getId())};
String[] userIdArg = {Long.toString(status.getAuthor().getId())};
User user = status.getAuthor();
int flags = getStatusFlags(db, status.getId());
if (status.isReposted()) {
flags |= REPOST_MASK;
} else {
flags &= ~REPOST_MASK;
}
if (status.isFavorited()) {
flags |= FAVORITE_MASK;
} else {
flags &= ~FAVORITE_MASK;
}
if (status.isBookmarked()) {
flags |= BOOKMARK_MASK;
} else {
flags &= ~BOOKMARK_MASK;
}
ContentValues statusUpdate = new ContentValues(7);
statusUpdate.put(StatusTable.TEXT, status.getText());
statusUpdate.put(StatusTable.REPOST, status.getRepostCount());
statusUpdate.put(StatusTable.FAVORITE, status.getFavoriteCount());
statusUpdate.put(StatusTable.REPLY, status.getReplyCount());
statusUpdate.put(StatusTable.REPLYNAME, status.getReplyName());
statusUpdate.put(StatusTable.SOURCE, status.getSource());
statusUpdate.put(StatusTable.URL, status.getUrl());
ContentValues userUpdate = new ContentValues(9);
userUpdate.put(UserTable.USERNAME, user.getUsername());
userUpdate.put(UserTable.SCREENNAME, user.getScreenname());
userUpdate.put(UserTable.IMAGE, user.getOriginalProfileImageUrl());
userUpdate.put(UserTable.DESCRIPTION, user.getDescription());
userUpdate.put(UserTable.LINK, user.getProfileUrl());
userUpdate.put(UserTable.LOCATION, user.getLocation());
userUpdate.put(UserTable.BANNER, user.getOriginalBannerImageUrl());
userUpdate.put(UserTable.FRIENDS, user.getFollowing());
userUpdate.put(UserTable.FOLLOWER, user.getFollower());
db.updateWithOnConflict(StatusTable.NAME, statusUpdate, STATUS_SELECT, statusIdArg, CONFLICT_REPLACE);
db.updateWithOnConflict(UserTable.NAME, userUpdate, USER_SELECT, userIdArg, CONFLICT_IGNORE);
saveStatusFlags(db, status, flags);
}
/**
* Get SQLite instance for reading database
*

View File

@ -127,7 +127,7 @@ public class DatabaseAccount implements Account {
return Configuration.MASTODON;
default:
return Configuration.NONE;
return Configuration.FALLBACK_CONFIG;
}
}

View File

@ -14,23 +14,21 @@ import java.io.Serializable;
*/
public interface Account extends Serializable {
/**
* API ID if undefined
*/
int API_NONE = 0;
/**
* API ID for twitter version 1.1
* used in database tables!
*/
int API_TWITTER_1 = 1;
/**
* API ID for twitter version 2.0
* used in database tables!
*/
int API_TWITTER_2 = 3;
/**
* API ID used for Mastodon accounts
* used in database tables!
*/
int API_MASTODON = 2;

View File

@ -197,8 +197,7 @@ public class LoginActivity extends AppCompatActivity implements ActivityResultCa
// use userdefined or default token keys
if (connection.useTokens() || Tokens.USE_DEFAULT_KEYS) {
Toast.makeText(getApplicationContext(), R.string.info_open_twitter_login, LENGTH_LONG).show();
LoginParam param = new LoginParam(LoginParam.MODE_REQUEST, connection, "");
loginAsync.setConnection(this, connection.getApiType());
LoginParam param = new LoginParam(LoginParam.MODE_REQUEST, connection.getApiType(), connection, "");
loginAsync.execute(param, this);
}
// no tokens are set, print error message
@ -209,8 +208,7 @@ public class LoginActivity extends AppCompatActivity implements ActivityResultCa
// generate Mastodon login
else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) {
Toast.makeText(getApplicationContext(), R.string.info_open_mastodon_login, LENGTH_LONG).show();
LoginParam param = new LoginParam(LoginParam.MODE_REQUEST, connection, "");
loginAsync.setConnection(this, connection.getApiType());
LoginParam param = new LoginParam(LoginParam.MODE_REQUEST, connection.getApiType(), connection, "");
loginAsync.execute(param, this);
}
}
@ -227,8 +225,7 @@ public class LoginActivity extends AppCompatActivity implements ActivityResultCa
else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_TWITTER) {
if (connection.useTokens() || Tokens.USE_DEFAULT_KEYS) {
Toast.makeText(getApplicationContext(), R.string.info_login_to_twitter, LENGTH_LONG).show();
LoginParam param = new LoginParam(LoginParam.MODE_LOGIN, connection, code);
loginAsync.setConnection(this, connection.getApiType());
LoginParam param = new LoginParam(LoginParam.MODE_LOGIN, connection.getApiType(), connection, code);
loginAsync.execute(param, this);
} else {
Toast.makeText(getApplicationContext(), R.string.info_missing_api_keys, LENGTH_SHORT).show();
@ -237,8 +234,7 @@ public class LoginActivity extends AppCompatActivity implements ActivityResultCa
// login to mastodon
else if (hostSelector.getSelectedItemId() == NetworkAdapter.ID_MASTODON) {
Toast.makeText(getApplicationContext(), R.string.info_login_to_mastodon, LENGTH_LONG).show();
LoginParam param = new LoginParam(LoginParam.MODE_LOGIN, connection, code);
loginAsync.setConnection(this, connection.getApiType());
LoginParam param = new LoginParam(LoginParam.MODE_LOGIN, connection.getApiType(), connection, code);
loginAsync.execute(param, this);
}
}

View File

@ -294,7 +294,7 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul
// remove user from list
else if (type == ConfirmDialog.LIST_REMOVE_USER) {
if (listManagerAsync.isIdle() && userList != null && user != null) {
ListManagerParam param = new ListManagerParam(ListManagerParam.DEL_USER, userList.getId(), user.getScreenname());
ListManagerParam param = new ListManagerParam(ListManagerParam.REMOVE, userList.getId(), user.getScreenname());
listManagerAsync.execute(param, this::updateList);
}
}
@ -331,7 +331,7 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul
if (USERNAME_PATTERN.matcher(query).matches()) {
if (listManagerAsync.isIdle()) {
Toast.makeText(getApplicationContext(), R.string.info_adding_user_to_list, Toast.LENGTH_SHORT).show();
ListManagerParam param = new ListManagerParam(ListManagerParam.ADD_USER, userList.getId(), query);
ListManagerParam param = new ListManagerParam(ListManagerParam.ADD, userList.getId(), query);
listManagerAsync.execute(param, this::updateList);
return true;
}

View File

@ -196,7 +196,7 @@ public class UserlistEditor extends AppCompatActivity implements OnClickListener
mHolder = new UserListUpdate(titleStr, descrStr, isPublic, userList.getId());
} else {
// create new one
mHolder = new UserListUpdate(titleStr, descrStr, isPublic, UserListUpdate.NEW_LIST);
mHolder = new UserListUpdate(titleStr, descrStr, isPublic);
}
updaterAsync.execute(mHolder, this);
loadingCircle.show();

View File

@ -250,7 +250,7 @@ public class StatusFragment extends ListFragment implements StatusSelectListener
case STATUS_FRAGMENT_REPLY:
if (index == CLEAR_LIST)
request = new StatusParameter(StatusParameter.REPLIES_OFFLINE, id, sinceId, maxId, index, search);
request = new StatusParameter(StatusParameter.REPLIES_LOCAL, id, sinceId, maxId, index, search);
else
request = new StatusParameter(StatusParameter.REPLIES, id, sinceId, maxId, index, search);
break;

View File

@ -163,14 +163,21 @@ public class UserListFragment extends ListFragment implements ListClickListener,
@Override
public void onResult(UserlistResult result) {
setRefresh(false);
if (result.userlists != null) {
adapter.addItems(result.userlists);
} else if (getContext() != null) {
String message = ErrorHandler.getErrorMessage(getContext(), result.exception);
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
adapter.disableLoading();
switch (result.mode) {
case UserlistResult.MEMBERSHIP:
case UserlistResult.OWNERSHIP:
if (result.userlists != null) {
adapter.addItems(result.userlists);
}
break;
case UserlistResult.ERROR:
String message = ErrorHandler.getErrorMessage(getContext(), result.exception);
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
adapter.disableLoading();
break;
}
setRefresh(false);
}
/**
@ -180,11 +187,11 @@ public class UserListFragment extends ListFragment implements ListClickListener,
UserlistParam param;
switch (type) {
case LIST_USER_OWNS:
param = new UserlistParam(UserlistParam.LOAD_USERLISTS, id, cursor);
param = new UserlistParam(UserlistParam.OWNERSHIP, id, cursor);
break;
case LIST_USER_SUBSCR_TO:
param = new UserlistParam(UserlistParam.LOAD_MEMBERSHIPS, id, cursor);
param = new UserlistParam(UserlistParam.MEMBERSHIP, id, cursor);
break;
default: