code cleanup

This commit is contained in:
Mariotaku Lee 2017-12-04 12:50:14 +08:00
parent 9b46b0a41b
commit 7cbed18d05
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
89 changed files with 466 additions and 860 deletions

View File

@ -86,16 +86,15 @@ public class ParcelableLocation implements Parcelable {
@Nullable
public static ParcelableLocation valueOf(@NonNull final String locationString) {
if (locationString == null) return null;
final String[] longlat = locationString.split(",");
if (longlat.length != 2) {
final String[] latLong = locationString.split(",");
if (latLong.length != 2) {
return null;
}
ParcelableLocation obj = new ParcelableLocation();
try {
obj.latitude = Double.parseDouble(longlat[0]);
obj.longitude = Double.parseDouble(longlat[1]);
obj.latitude = Double.parseDouble(latLong[0]);
obj.longitude = Double.parseDouble(latLong[1]);
} catch (NumberFormatException e) {
return null;
}

View File

@ -220,6 +220,7 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "lang")
@CursorField(Statuses.LANG)
@Nullable
public String lang;
@JsonField(name = "user_name")
@ -282,10 +283,12 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "location")
@CursorField(value = Statuses.LOCATION, converter = ParcelableLocation.Converter.class)
@Nullable
public ParcelableLocation location;
@JsonField(name = "place_full_name")
@CursorField(value = Statuses.PLACE_FULL_NAME)
@Nullable
public String place_full_name;
@JsonField(name = "mentions")

View File

@ -0,0 +1,33 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.ktextension
import org.junit.Assert
import org.junit.Test
class NumberExtensionsKtTest {
@Test
fun toPrettyDecimal() {
Assert.assertEquals("1", 1.0.toString(2))
Assert.assertEquals("1.01", 1.01.toString(2))
Assert.assertEquals("1.56", 1.5555555.toString(2))
}
}

View File

@ -26,12 +26,12 @@ import com.bluelinelabs.logansquare.LoganSquare
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.all
import org.mariotaku.ktextension.deadline
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.isAccountValid
import org.mariotaku.twidere.extension.model.updateDetails
import org.mariotaku.twidere.extension.ownedAccounts
import org.mariotaku.twidere.extension.removeAccount
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.test.R
import java.io.InputStream
import java.lang.Exception
@ -62,7 +62,7 @@ object TestAccountUtils {
return@mapNotNull am.removeAccount(account).deadline(1, TimeUnit.SECONDS)
}, cancelOthersOnError = false).get()
DebugLog.d(msg = "Removed accounts: $result")
val existingAccounts = AccountUtils.getAllAccountDetails(am, false)
val existingAccounts = am.getAllDetails(false)
testAccounts.forEach { details ->
if (existingAccounts.any { it.account == details.account || it.key == details.key }) {
return@forEach
@ -75,7 +75,7 @@ object TestAccountUtils {
fun removeTestAccounts(): Promise<List<Bundle>, Exception> {
val targetContext = InstrumentationRegistry.getTargetContext()
val am = AccountManager.get(targetContext)
val existingAccounts = AccountUtils.getAllAccountDetails(am, false)
val existingAccounts = am.getAllDetails(false)
return all(existingAccounts.mapNotNull {
if (!it.test) return@mapNotNull null
return@mapNotNull am.removeAccount(it.account)

View File

@ -1,37 +0,0 @@
package org.mariotaku.twidere.util
import org.junit.Assert
import org.junit.Test
/**
* Created by mariotaku on 16/1/31.
*/
class TwidereArrayUtilsTest {
@Test
@Throws(Exception::class)
fun testMergeArray() {
val array1 = arrayOf("1", "2")
val array2 = arrayOf("1", "2")
val array3: Array<String>? = null
//noinspection ConstantConditions
val merged = arrayOfNulls<String>(TwidereArrayUtils.arraysLength(array1, array2, array3))
//noinspection ConstantConditions
TwidereArrayUtils.mergeArray(merged, array1, array2, array3)
val expected = arrayOf("1", "2", "1", "2")
Assert.assertArrayEquals(expected, merged)
}
@Test
@Throws(Exception::class)
fun testArraysLength() {
val array1 = arrayOf("1", "2")
val array2 = arrayOf("1", "2")
val array3: Array<String>? = null
//noinspection ConstantConditions
Assert.assertEquals(4, TwidereArrayUtils.arraysLength(array1, array2, array3))
Assert.assertEquals(6, TwidereArrayUtils.arraysLength(array1, array2, array2))
}
}

View File

@ -1,6 +1,5 @@
package org.mariotaku.twidere.util
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith

View File

@ -39,11 +39,12 @@ import org.json.JSONObject
import org.mariotaku.ktextension.subArray
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.exception.NoAccountException
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.updateDetails
import org.mariotaku.twidere.extension.ownedAccounts
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.JsonSerializer
import java.io.InputStream
@ -260,7 +261,7 @@ class AccountsDumperPlugin(val context: Context) : DumperPlugin {
val gz = GZIPOutputStream(CipherOutputStream(base64, cipher))
// write accounts
val accounts = AccountUtils.getAllAccountDetails(this, true).toList()
val accounts = this.getAllDetails(true).toList()
JsonSerializer.serialize(accounts, gz, AccountDetails::class.java)
}
@ -310,7 +311,7 @@ class AccountsDumperPlugin(val context: Context) : DumperPlugin {
private fun AccountManager.docContext(forKey: String): DocumentContext {
val accountKey = UserKey.valueOf(forKey)
val details = AccountUtils.getAccountDetails(this, accountKey, true)
val details = getDetails(accountKey, true)
?: throw AccountNotFoundException()
val configuration = Configuration.builder()
.jsonProvider(JsonOrgJsonProvider())

View File

@ -37,14 +37,14 @@ import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.microblog.library.twitter.model.DirectMessage
import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ActivityTitleSummaryMessage
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.util.streaming.FanfouTimelineStreamCallback
import org.mariotaku.twidere.util.streaming.TwitterTimelineStreamCallback
@ -74,7 +74,7 @@ class UserStreamDumperPlugin(val context: Context) : DumperPlugin {
val verboseMode = cmdLine.hasOption("verbose")
val accountKey = UserKey.valueOf(argsList[0])
val am = AccountManager.get(context)
val account = AccountUtils.getAccountDetails(am, accountKey, true) ?: return
val account = am.getDetails(accountKey, true) ?: return
when (account.type) {
AccountType.TWITTER -> {
beginTwitterStream(account, dumpContext, includeInteractions, includeTimeline,

View File

@ -1,197 +0,0 @@
package org.mariotaku.twidere.model.util;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.annotation.AccountType;
import org.mariotaku.twidere.annotation.AuthTypeInt;
import org.mariotaku.twidere.extension.AccountManagerExtensionsKt;
import org.mariotaku.twidere.extension.model.AccountExtensionsKt;
import org.mariotaku.twidere.model.AccountDetails;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.account.cred.Credentials;
import org.mariotaku.twidere.util.Utils;
import java.util.Arrays;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_ACTIVATED;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_COLOR;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_CREDS_TYPE;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_EXTRAS;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_KEY;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_POSITION;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_TEST;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_TYPE;
import static org.mariotaku.twidere.TwidereConstants.ACCOUNT_USER_DATA_USER;
/**
* Created by mariotaku on 2016/12/3.
*/
public class AccountUtils {
public static final String[] ACCOUNT_USER_DATA_KEYS = {
ACCOUNT_USER_DATA_KEY,
ACCOUNT_USER_DATA_TYPE,
ACCOUNT_USER_DATA_CREDS_TYPE,
ACCOUNT_USER_DATA_ACTIVATED,
ACCOUNT_USER_DATA_USER,
ACCOUNT_USER_DATA_EXTRAS,
ACCOUNT_USER_DATA_COLOR,
ACCOUNT_USER_DATA_POSITION,
ACCOUNT_USER_DATA_TEST,
};
@Nullable
public static Account findByAccountKey(@NonNull AccountManager am, @NonNull UserKey userKey) {
//noinspection MissingPermission
for (Account account : AccountManagerExtensionsKt.getOwnedAccounts(am)) {
if (userKey.equals(AccountExtensionsKt.getAccountKey(account, am))) {
return account;
}
}
return null;
}
public static AccountDetails[] getAllAccountDetails(@NonNull AccountManager am, @NonNull Account[] accounts, boolean getCredentials) {
AccountDetails[] details = new AccountDetails[accounts.length];
for (int i = 0; i < accounts.length; i++) {
details[i] = getAccountDetails(am, accounts[i], getCredentials);
}
Arrays.sort(details);
return details;
}
public static AccountDetails[] getAllAccountDetails(@NonNull AccountManager am, @NonNull UserKey[] accountKeys, boolean getCredentials) {
AccountDetails[] details = new AccountDetails[accountKeys.length];
for (int i = 0; i < accountKeys.length; i++) {
details[i] = getAccountDetails(am, accountKeys[i], getCredentials);
}
Arrays.sort(details);
return details;
}
public static AccountDetails[] getAllAccountDetails(@NonNull AccountManager am, boolean getCredentials) {
//noinspection MissingPermission
return getAllAccountDetails(am, AccountManagerExtensionsKt.getOwnedAccounts(am), getCredentials);
}
@Nullable
public static AccountDetails getAccountDetails(@NonNull AccountManager am, @NonNull UserKey accountKey, boolean getCredentials) {
final Account account = findByAccountKey(am, accountKey);
if (account == null) return null;
return getAccountDetails(am, account, getCredentials);
}
@Nullable
public static AccountDetails getDefaultAccountDetails(@NonNull Context context, @NonNull AccountManager am, boolean getCredentials) {
final UserKey accountKey = Utils.INSTANCE.getDefaultAccountKey(context);
if (accountKey == null) return null;
final Account account = findByAccountKey(am, accountKey);
if (account == null) return null;
return getAccountDetails(am, account, getCredentials);
}
public static AccountDetails getAccountDetails(@NonNull AccountManager am, @NonNull Account account, boolean getCredentials) {
AccountDetails details = new AccountDetails();
details.key = AccountExtensionsKt.getAccountKey(account, am);
details.account = account;
details.color = AccountExtensionsKt.getColor(account, am);
details.position = AccountExtensionsKt.getPosition(account, am);
details.activated = AccountExtensionsKt.isActivated(account, am);
details.type = AccountExtensionsKt.getAccountType(account, am);
details.credentials_type = AccountExtensionsKt.getCredentialsType(account, am);
details.user = AccountExtensionsKt.getAccountUser(account, am);
details.user.color = details.color;
details.extras = AccountExtensionsKt.getAccountExtras(account, am);
if (getCredentials) {
details.credentials = AccountExtensionsKt.getCredentials(account, am);
}
details.test = AccountExtensionsKt.isTest(account, am);
return details;
}
@Nullable
public static Account findByScreenName(AccountManager am, @NonNull String screenName) {
//noinspection MissingPermission
for (Account account : AccountManagerExtensionsKt.getOwnedAccounts(am)) {
if (screenName.equalsIgnoreCase(AccountExtensionsKt.getAccountUser(account, am).screen_name)) {
return account;
}
}
return null;
}
public static boolean isOfficial(@NonNull final Context context, @NonNull final UserKey accountKey) {
AccountManager am = AccountManager.get(context);
Account account = AccountUtils.findByAccountKey(am, accountKey);
if (account == null) return false;
return AccountExtensionsKt.isOfficial(account, am, context);
}
public static boolean hasOfficialKeyAccount(Context context) {
final AccountManager am = AccountManager.get(context);
//noinspection MissingPermission
for (Account account : AccountManagerExtensionsKt.getOwnedAccounts(am)) {
if (AccountExtensionsKt.isOfficial(account, am, context)) {
return true;
}
}
return false;
}
public static int getAccountTypeIcon(@Nullable String accountType) {
if (accountType == null) return R.drawable.ic_account_logo_twitter;
switch (accountType) {
case AccountType.TWITTER: {
return R.drawable.ic_account_logo_twitter;
}
case AccountType.FANFOU: {
return R.drawable.ic_account_logo_fanfou;
}
case AccountType.STATUSNET: {
return R.drawable.ic_account_logo_statusnet;
}
case AccountType.MASTODON: {
return R.drawable.ic_account_logo_mastodon;
}
}
return R.drawable.ic_account_logo_twitter;
}
public static String getCredentialsType(@AuthTypeInt int authType) {
switch (authType) {
case AuthTypeInt.OAUTH:
return Credentials.Type.OAUTH;
case AuthTypeInt.BASIC:
return Credentials.Type.BASIC;
case AuthTypeInt.TWIP_O_MODE:
return Credentials.Type.EMPTY;
case AuthTypeInt.XAUTH:
return Credentials.Type.XAUTH;
case AuthTypeInt.OAUTH2:
return Credentials.Type.OAUTH2;
}
throw new UnsupportedOperationException();
}
public static boolean hasAccountPermission(@NonNull AccountManager am) {
try {
//noinspection MissingPermission
AccountManagerExtensionsKt.getOwnedAccounts(am);
} catch (SecurityException e) {
return false;
}
return true;
}
}

View File

@ -28,9 +28,6 @@ import org.mariotaku.twidere.model.CronExpression;
import java.io.IOException;
import java.text.ParseException;
/**
* Created by mariotaku on 2017/8/19.
*/
public class CronExpressionConverter implements TypeConverter<CronExpression> {
@Override

View File

@ -1,45 +0,0 @@
package org.mariotaku.twidere.model.util;
import org.mariotaku.microblog.library.statusnet.model.Group;
import org.mariotaku.twidere.model.ParcelableGroup;
import org.mariotaku.twidere.model.UserKey;
import java.util.Date;
/**
* Created by mariotaku on 16/3/9.
*/
public class ParcelableGroupUtils {
private ParcelableGroupUtils() {
}
public static ParcelableGroup from(Group group, UserKey accountKey, int position, boolean member) {
ParcelableGroup obj = new ParcelableGroup();
obj.account_key = accountKey;
obj.member = member;
obj.position = position;
obj.id = group.getId();
obj.nickname = group.getNickname();
obj.homepage = group.getHomepage();
obj.fullname = group.getFullname();
obj.url = group.getUrl();
obj.description = group.getDescription();
obj.location = group.getLocation();
obj.created = getTime(group.getCreated());
obj.modified = getTime(group.getModified());
obj.admin_count = group.getAdminCount();
obj.member_count = group.getMemberCount();
obj.original_logo = group.getOriginalLogo();
obj.homepage_logo = group.getHomepageLogo();
obj.stream_logo = group.getStreamLogo();
obj.mini_logo = group.getMiniLogo();
obj.blocked = group.isBlocked();
obj.id = group.getId();
return obj;
}
private static long getTime(Date date) {
if (date == null) return -1;
return date.getTime();
}
}

View File

@ -1,52 +0,0 @@
package org.mariotaku.twidere.model.util;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.mariotaku.microblog.library.twitter.model.GeoLocation;
import org.mariotaku.twidere.model.ParcelableLocation;
import org.mariotaku.twidere.util.InternalParseUtils;
/**
* Created by mariotaku on 16/3/8.
*/
public class ParcelableLocationUtils {
private ParcelableLocationUtils() {
}
public static String getHumanReadableString(@NonNull ParcelableLocation obj, int decimalDigits) {
return String.format("%s,%s", InternalParseUtils.parsePrettyDecimal(obj.latitude, decimalDigits),
InternalParseUtils.parsePrettyDecimal(obj.longitude, decimalDigits));
}
@Nullable
public static ParcelableLocation fromGeoLocation(@Nullable GeoLocation geoLocation) {
if (geoLocation == null) return null;
final ParcelableLocation result = new ParcelableLocation();
result.latitude = geoLocation.getLatitude();
result.longitude = geoLocation.getLongitude();
return result;
}
@Nullable
public static ParcelableLocation fromLocation(@Nullable Location location) {
if (location == null) return null;
final ParcelableLocation result = new ParcelableLocation();
result.latitude = location.getLatitude();
result.longitude = location.getLongitude();
return result;
}
public static boolean isValidLocation(final ParcelableLocation location) {
return location != null && !Double.isNaN(location.latitude) && !Double.isNaN(location.longitude);
}
public static GeoLocation toGeoLocation(final ParcelableLocation location) {
return isValidLocation(location) ? new GeoLocation(location.latitude, location.longitude) : null;
}
public static boolean isValidLocation(double latitude, double longitude) {
return !Double.isNaN(latitude) && !Double.isNaN(longitude);
}
}

View File

@ -1,52 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util;
import android.support.annotation.Nullable;
import android.text.TextUtils;
/**
* Common tool to check strings, objects etc.
* Created by mariotaku on 15/11/22.
*/
public class CheckUtils {
private CheckUtils() {
}
public static boolean checkRange(@Nullable final CharSequence text, int start, int end) {
if (text == null) return false;
if (end < start) {
return false;
}
int len = text.length();
if (start > len || end > len) {
return false;
}
return !(start < 0 || end < 0);
}
public static boolean isValidLocale(String locale) {
return !TextUtils.isEmpty(locale) && !"und".equals(locale);
}
}

View File

@ -46,13 +46,4 @@ public class CompareUtils {
return object1.equals(object2);
}
public static boolean textEquals(CharSequence text1, CharSequence text2) {
if (text1 == null || text2 == null) return text1 == text2;
if (text1 == text2) return true;
if (text1.length() != text2.length()) return false;
for (int i = 0, j = text1.length(); i < j; i++) {
if (text1.charAt(i) != text2.charAt(i)) return false;
}
return true;
}
}

View File

@ -1,23 +0,0 @@
package org.mariotaku.twidere.util;
import java.util.Locale;
/**
* Created by mariotaku on 16/3/8.
*/
public class InternalParseUtils {
private InternalParseUtils() {
}
public static String parsePrettyDecimal(double num, int decimalDigits) {
String result = String.format(Locale.US, "%." + decimalDigits + "f", num);
int dotIdx = result.lastIndexOf('.');
if (dotIdx == -1) return result;
int i;
for (i = result.length() - 1; i >= 0; i--) {
if (result.charAt(i) != '0') break;
}
return result.substring(0, i == dotIdx ? dotIdx : i + 1);
}
}

View File

@ -1,34 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mariotaku.twidere.util;
public final class ParseUtils {
private ParseUtils() {
}
public static String parseString(final Object object) {
return parseString(object, null);
}
public static String parseString(final Object object, final String def) {
if (object == null) return def;
return String.valueOf(object);
}
}

View File

@ -25,9 +25,6 @@ import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewParent;
/**
* Created by mariotaku on 15/4/13.
*/
public class RecyclerViewUtils {
private RecyclerViewUtils() {

View File

@ -48,16 +48,7 @@ public final class TwidereArrayUtils {
return true;
}
public static int arraysLength(@NonNull final Object... arrays) {
int length = 0;
for (Object array : arrays) {
if (array == null) continue;
length += Array.getLength(array);
}
return length;
}
@Deprecated
public static void mergeArray(final Object dest, @NonNull final Object... arrays) {
for (int i = 0, j = arrays.length, k = 0; i < j; i++) {
final Object array = arrays[i];
@ -88,7 +79,8 @@ public final class TwidereArrayUtils {
if (array == null) return null;
final String[] stringArray = new String[end - start];
for (int i = start; i < end; i++) {
stringArray[i - start] = ParseUtils.parseString(Array.get(array, i));
Object item = Array.get(array, i);
stringArray[i - start] = item != null ? item.toString() : null;
}
return stringArray;
}

View File

@ -106,8 +106,8 @@ public final class TwidereLinkify implements Constants {
}
public void applyAllLinks(@Nullable Spannable text, @Nullable final UserKey accountKey,
final long extraId, final boolean sensitive,
final boolean skipLinksInText) {
final long extraId, final boolean sensitive,
final boolean skipLinksInText) {
applyAllLinks(text, mOnLinkClickListener, accountKey, extraId, sensitive,
mHighlightOption, skipLinksInText);
}
@ -168,7 +168,7 @@ public final class TwidereLinkify implements Constants {
/**
* Applies a regex to the text of a TextView turning the matches into links.
*/
private void addLinks(final Spannable string, @Nullable final UserKey accountKey,
private void addLinks(@NonNull final Spannable string, @Nullable final UserKey accountKey,
final long extraId, final int type, final boolean sensitive,
final OnLinkClickListener listener, final int highlightOption) {
switch (type) {
@ -220,7 +220,7 @@ public final class TwidereLinkify implements Constants {
break;
}
case LINK_TYPE_LINK_IN_TEXT: {
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string));
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(string.toString());
for (final Extractor.Entity entity : urls) {
final int start = entity.getStart(), end = entity.getEnd();
if (entity.getType() != Extractor.Entity.Type.URL
@ -248,7 +248,7 @@ public final class TwidereLinkify implements Constants {
}
private boolean addMentionOrListLinks(final Spannable spannable, final UserKey accountKey,
final long extraId, final int highlightOption, final OnLinkClickListener listener) {
final long extraId, final int highlightOption, final OnLinkClickListener listener) {
boolean hasMatches = false;
// Extract lists from status text
final Matcher matcher = Regex.VALID_MENTION_OR_LIST.matcher(spannable);
@ -293,8 +293,8 @@ public final class TwidereLinkify implements Constants {
}
private void applyLink(@NonNull final String url, @Nullable final String orig, final int start, final int end,
final Spannable text, @Nullable final UserKey accountKey, final long extraId, final int type, final boolean sensitive,
final int highlightOption, final OnLinkClickListener listener) {
final Spannable text, @Nullable final UserKey accountKey, final long extraId, final int type, final boolean sensitive,
final int highlightOption, final OnLinkClickListener listener) {
final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountKey, extraId, type, sensitive,
highlightOption, start, end, listener);
text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -309,6 +309,6 @@ public final class TwidereLinkify implements Constants {
public interface OnLinkClickListener {
boolean onLinkClick(@NonNull String link, @Nullable String orig, @Nullable UserKey accountKey, long extraId, int type,
boolean sensitive, int start, int end);
boolean sensitive, int start, int end);
}
}

View File

@ -1,63 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util;
import android.support.annotation.NonNull;
import android.text.Spannable;
import android.text.Spanned;
import org.mariotaku.twidere.text.ZeroWidthSpan;
/**
* Created by mariotaku on 14/12/23.
*/
public class TwidereStringUtils {
private TwidereStringUtils() {
}
public static boolean regionMatchesIgnoreCase(@NonNull final String string, final int thisStart,
@NonNull final String match, final int start,
final int length) {
return string.substring(thisStart, thisStart + length).equalsIgnoreCase(match.substring(start, start + length));
}
public static boolean startsWithIgnoreCase(@NonNull String string, @NonNull String prefix) {
return startsWithIgnoreCase(string, prefix, 0);
}
public static boolean startsWithIgnoreCase(@NonNull String string, @NonNull String prefix,
int start) {
if (prefix.length() > string.length()) return false;
return regionMatchesIgnoreCase(string, start, prefix, 0, prefix.length());
}
/**
* Fix to https://github.com/TwidereProject/Twidere-Android/issues/449
*/
public static void fixSHY(Spannable string) {
for (int i = 0, j = string.length(); i < j; i++) {
if (string.charAt(i) == '\u00ad') {
string.setSpan(new ZeroWidthSpan(), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}

View File

@ -17,13 +17,13 @@ import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.restfu.http.MultiValueMap;
import org.mariotaku.restfu.http.RestHttpClient;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.twidere.extension.AccountManagerExtensionsKt;
import org.mariotaku.twidere.extension.model.AccountExtensionsKt;
import org.mariotaku.twidere.extension.model.CredentialsExtensionsKt;
import org.mariotaku.twidere.model.CacheMetadata;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.account.cred.Credentials;
import org.mariotaku.twidere.model.util.AccountUtils;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.UserAgentUtils;
@ -92,7 +92,7 @@ public class TwidereMediaDownloader implements MediaDownloader {
UserKey accountKey = ((MediaExtra) extra).getAccountKey();
if (accountKey != null) {
final AccountManager am = AccountManager.get(context);
Account account = AccountUtils.findByAccountKey(am, accountKey);
Account account = AccountManagerExtensionsKt.findAccount(am, accountKey);
if (account != null) {
credentials = AccountExtensionsKt.getCredentials(account, am);
}

View File

@ -24,6 +24,7 @@ import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
@ -31,7 +32,6 @@ import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mariotaku.twidere.util.CompareUtils;
import org.mariotaku.twidere.util.support.view.ViewOutlineProviderCompat;
import org.mariotaku.twidere.view.iface.IForegroundView;
@ -106,7 +106,7 @@ public final class ViewSupport {
}
public static TextView findViewByText(View view, CharSequence text) {
if (view instanceof TextView && CompareUtils.textEquals(text, ((TextView) view).getText()))
if (view instanceof TextView && TextUtils.equals(text, ((TextView) view).getText()))
return (TextView) view;
if (view instanceof ViewGroup) {
for (int i = 0, j = ((ViewGroup) view).getChildCount(); i < j; i++) {

View File

@ -42,11 +42,22 @@ operator fun Int.contains(i: Int): Boolean = (this and i) == i
*/
operator fun Long.contains(i: Long): Boolean = (this and i) == i
fun Number.toLocalizedString(locale: Locale = Locale.getDefault()): String {
fun Number.toString(locale: Locale = Locale.getDefault()): String {
val nf = NumberFormat.getInstance(locale)
return nf.format(this)
}
fun Double.toString(decimalDigits: Int): String {
var str = String.format(Locale.US, "%." + decimalDigits + "f", this)
val dotIdx = str.lastIndexOf('.')
if (dotIdx == -1) return str
str = str.substring(0, (dotIdx + decimalDigits + 1).coerceAtMost(str.length)).trimEnd('0')
if (str.endsWith('.')) {
str = str.substring(0, str.length - 1)
}
return str
}
val Int.nextPowerOf2: Int
get() {
var n = this

View File

@ -19,6 +19,9 @@
package org.mariotaku.ktextension
import android.text.Spannable
import android.text.Spanned
import org.mariotaku.twidere.text.ZeroWidthSpan
import java.text.Normalizer
fun CharSequence.appendTo(sb: StringBuilder) {
@ -29,4 +32,15 @@ operator fun CharSequence.times(n: Int): String = repeat(n)
fun CharSequence.normalized(form: Normalizer.Form): String {
return Normalizer.normalize(this, form)
}
/**
* Fix to https://github.com/TwidereProject/Twidere-Android/issues/449
*/
fun Spannable.fixSHY() {
forEachIndexed { i, ch ->
if (ch == '\u00ad') {
setSpan(ZeroWidthSpan(), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}

View File

@ -35,10 +35,10 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.adapter.AccountDetailsAdapter
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.model.isOAuth
import org.mariotaku.twidere.extension.ownedAccounts
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.DataStoreUtils
class AccountSelectorActivity : BaseActivity(), OnItemClickListener {
@ -100,7 +100,7 @@ class AccountSelectorActivity : BaseActivity(), OnItemClickListener {
switchEnabled = !isSingleSelection
sortEnabled = false
val am = AccountManager.get(context)
val allAccountDetails = AccountUtils.getAllAccountDetails(am, am.ownedAccounts, false)
val allAccountDetails = am.getAllDetails(am.ownedAccounts, false)
val extraKeys = onlyIncludeKeys
val oauthOnly = isOAuthOnly
val accountHost = accountHost

View File

@ -69,7 +69,6 @@ import org.mariotaku.kpreferences.edit
import org.mariotaku.kpreferences.get
import org.mariotaku.kpreferences.set
import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.mastodon.annotation.StatusVisibility
import org.mariotaku.pickncrop.library.MediaPickerActivity
import org.mariotaku.twidere.Constants.*
@ -90,8 +89,6 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras
import org.mariotaku.twidere.model.schedule.ScheduleInfo
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.preference.ComponentPickerPreference
import org.mariotaku.twidere.promise.UpdateStatusPromise
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
@ -244,7 +241,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
finish()
return
}
val accountDetails = AccountUtils.getAllAccountDetails(am, accounts, true)
val accountDetails = am.getAllDetails(accounts, true)
val defaultAccountKeys = accountDetails.mapToArray(AccountDetails::key)
menuBar.setOnMenuItemClickListener(this)
setupEditText()
@ -972,8 +969,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
private fun handleReplyIntent(status: ParcelableStatus?): Boolean {
if (status == null) return false
val am = AccountManager.get(this)
val statusAccount = AccountUtils.getAccountDetails(am, status.account_key,
false) ?: return false
val statusAccount = am.getDetails(status.account_key, false) ?: return false
val accountUser = statusAccount.user
val mentions = ArrayList<String>()
val userAcct = status.user_acct
@ -1377,7 +1373,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
if (location == null) {
locationLabel.setText(R.string.unknown_location)
} else if (preferences[attachPreciseLocationKey]) {
locationLabel.spannable = ParcelableLocationUtils.getHumanReadableString(location, 3)
locationLabel.spannable = location.getHumanReadableString(3)
} else if (locationLabel.tag == null || location != recentLocation) {
loadPlaceName(location)
}
@ -1843,7 +1839,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
locationLabel.setText(R.string.no_location)
}
preferences[attachPreciseLocationKey] -> {
locationLabel.string = ParcelableLocationUtils.getHumanReadableString(location, 3)
locationLabel.string = location.getHumanReadableString(3)
}
else -> {
val tag = locationLabel.tag
@ -2001,7 +1997,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
private val activity by weak(activity)
override fun onLocationChanged(location: Location) {
activity?.setRecentLocation(ParcelableLocationUtils.fromLocation(location))
activity?.setRecentLocation(ParcelableLocation(location.latitude, location.longitude))
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {

View File

@ -58,10 +58,10 @@ import org.mariotaku.twidere.constant.themeKey
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.hasInvalidAccount
import org.mariotaku.twidere.extension.hasPermission
import org.mariotaku.twidere.extension.model.displayingScore
import org.mariotaku.twidere.extension.model.shouldShow
import org.mariotaku.twidere.model.presentation.LaunchPresentation
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.LaunchPresentationsPromises
import org.mariotaku.twidere.util.DeviceUtils
import org.mariotaku.twidere.util.OnLinkClickHandler
@ -270,7 +270,7 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
val am = AccountManager.get(this)
if (!DeviceUtils.checkCompatibility()) {
startActivity(Intent(this, IncompatibleAlertActivity::class.java))
} else if (!AccountUtils.hasAccountPermission(am)) {
} else if (!am.hasPermission()) {
Toast.makeText(this, R.string.message_toast_no_account_permission, Toast.LENGTH_SHORT).show()
} else if (am.hasInvalidAccount()) {
val intent = Intent(this, InvalidAccountAlertActivity::class.java)

View File

@ -59,14 +59,10 @@ import org.mariotaku.twidere.constant.KeyboardShortcutConstants.ACTION_NAVIGATIO
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.extension.appendQueryParameterIgnoreNull
import org.mariotaku.twidere.extension.delete
import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.extension.ownedAccounts
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.SuggestionItem
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory
import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions
import org.mariotaku.twidere.util.EditTextEnterHandler
@ -101,11 +97,11 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM))
val am = AccountManager.get(this)
val accounts = AccountUtils.getAllAccountDetails(am, am.ownedAccounts, true).toList()
val accounts = am.getAllDetails(am.ownedAccounts, true)
val accountsSpinnerAdapter = AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon,
requestManager = requestManager)
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_simple_user)
accountsSpinnerAdapter.addAll(accounts)
accountsSpinnerAdapter.addAll(*accounts)
accountSpinner.adapter = accountsSpinnerAdapter
accountSpinner.onItemSelectedListener = this
if (savedInstanceState == null) {

View File

@ -103,7 +103,6 @@ import org.mariotaku.twidere.model.account.StatusNetAccountExtras
import org.mariotaku.twidere.model.account.TwitterAccountExtras
import org.mariotaku.twidere.model.account.cred.*
import org.mariotaku.twidere.model.analyzer.SignIn
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.*
@ -829,7 +828,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(context)
val account = AccountUtils.findByAccountKey(am, accountKey)
val account = am.findAccount(accountKey)
if (account != null) {
color = account.getColor(am)
}
@ -868,7 +867,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val accountKey = UserKey(apiAccount.id, host)
val user = apiAccount.toParcelable(accountKey)
val am = AccountManager.get(context)
val account = AccountUtils.findByAccountKey(am, accountKey)
val account = am.findAccount(accountKey)
if (account != null) {
color = account.getColor(am)
}
@ -968,7 +967,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
val account = AccountUtils.findByAccountKey(am, accountKey)
val account = am.findAccount(accountKey)
if (account != null) {
color = account.getColor(am)
}
@ -997,7 +996,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
val account = AccountUtils.findByAccountKey(am, accountKey)
val account = am.findAccount(accountKey)
if (account != null) {
color = account.getColor(am)
}
@ -1024,7 +1023,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
val account = AccountUtils.findByAccountKey(am, accountKey)
val account = am.findAccount(accountKey)
if (account != null) {
color = account.getColor(am)
}
@ -1155,7 +1154,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
}
fun updateAccount(am: AccountManager) {
val account = AccountUtils.findByAccountKey(am, user.key) ?: return
val account = am.findAccount(user.key) ?: return
writeAccountInfo { k, v ->
am.setUserData(account, k, v)
}

View File

@ -30,6 +30,7 @@ import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.data.fetcher.StatusesFetcher
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.api.mastodon.getLinkPagination
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
@ -39,7 +40,6 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.timeline.TimelineFilter
import org.mariotaku.twidere.model.util.AccountUtils
class StatusesLivePagedListProvider(
private val context: Context,
@ -99,8 +99,7 @@ class StatusesLivePagedListProvider(
private fun load(paging: Paging): List<ParcelableStatus>? {
val am = AccountManager.get(context)
val account = AccountUtils.getAccountDetails(am, accountKey, true) ?:
return emptyList()
val account = am.getDetails(accountKey, true) ?: return emptyList()
try {
when (account.type) {
AccountType.TWITTER -> {

View File

@ -20,23 +20,38 @@
package org.mariotaku.twidere.extension
import android.accounts.*
import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.support.annotation.RequiresApi
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.combine.and
import nl.komponents.kovenant.task
import nl.komponents.kovenant.thenApply
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.ktextension.set
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
private val ACCOUNT_USER_DATA_KEYS = arrayOf(ACCOUNT_USER_DATA_KEY, ACCOUNT_USER_DATA_TYPE,
ACCOUNT_USER_DATA_CREDS_TYPE, ACCOUNT_USER_DATA_ACTIVATED, ACCOUNT_USER_DATA_USER,
ACCOUNT_USER_DATA_EXTRAS, ACCOUNT_USER_DATA_COLOR, ACCOUNT_USER_DATA_POSITION, ACCOUNT_USER_DATA_TEST)
fun AccountManager.hasPermission(): Boolean {
try {
ownedAccounts
} catch (e: SecurityException) {
return false
}
return true
}
fun AccountManager.hasInvalidAccount(): Boolean {
val accounts = ownedAccounts
@ -57,7 +72,7 @@ fun AccountManager.renameTwidereAccount(oldAccount: Account, newName: String,
if (!addAccountExplicitly(newAccount, null, null)) {
throw AccountsException()
}
for (key in AccountUtils.ACCOUNT_USER_DATA_KEYS) {
for (key in ACCOUNT_USER_DATA_KEYS) {
setUserData(newAccount, key, getUserData(oldAccount, key))
}
setAuthToken(newAccount, ACCOUNT_AUTH_TOKEN_TYPE,
@ -111,37 +126,49 @@ fun AccountManager.findAccount(byKey: UserKey): Account? {
return ownedAccounts.find { byKey == it.getAccountKey(this) }
}
fun AccountManager.findAccount(byScreenName: String): Account? {
return ownedAccounts.find { byScreenName == it.getAccountUser(this).screen_name }
}
fun AccountManager.getDetails(key: UserKey, getCredentials: Boolean): AccountDetails? {
val account = findAccount(key) ?: return null
return getDetails(account, getCredentials)
}
fun AccountManager.getDetails(account: Account, getCredentials: Boolean): AccountDetails {
fun AccountManager.getDetails(account: Account, getCredentials: Boolean): AccountDetails? {
val details = AccountDetails()
details.key = account.getAccountKey(this)
details.account = account
details.color = account.getColor(this)
details.position = account.getPosition(this)
details.activated = account.isActivated(this)
details.type = account.getAccountType(this)
details.credentials_type = account.getCredentialsType(this)
details.user = account.getAccountUser(this)
details.user.color = details.color
try {
details.key = account.getAccountKey(this)
details.account = account
details.color = account.getColor(this)
details.position = account.getPosition(this)
details.activated = account.isActivated(this)
details.type = account.getAccountType(this)
details.credentials_type = account.getCredentialsType(this)
details.user = account.getAccountUser(this)
details.user.color = details.color
details.extras = account.getAccountExtras(this)
details.extras = account.getAccountExtras(this)
if (getCredentials) {
details.credentials = account.getCredentials(this)
if (getCredentials) {
details.credentials = account.getCredentials(this)
}
} catch (e: Exception) {
return null
}
return details
}
fun AccountManager.getDetailsOrThrow(account: Account, getCredentials: Boolean): AccountDetails {
return getDetails(account, getCredentials) ?: throw AccountNotFoundException()
}
fun AccountManager.getDetailsOrThrow(key: UserKey, getCredentials: Boolean): AccountDetails {
return getDetails(key, getCredentials) ?: throw AccountNotFoundException()
}
fun AccountManager.findMatchingDetailsOrThrow(key: UserKey): AccountDetails {
return AccountUtils.getAllAccountDetails(this, ownedAccounts, true).firstOrNull {
return this.getAllDetails(ownedAccounts, true).firstOrNull {
if (it.key == key) {
return@firstOrNull true
} else if (it.user.account_key == key) {
@ -151,10 +178,29 @@ fun AccountManager.findMatchingDetailsOrThrow(key: UserKey): AccountDetails {
} ?: throw AccountNotFoundException()
}
fun AccountManager.getAllDetails(accounts: Array<Account>, getCredentials: Boolean): Array<AccountDetails> {
return accounts.mapToArray { getDetailsOrThrow(it, getCredentials) }
}
fun AccountManager.getAllDetails(accountKeys: Array<UserKey>, getCredentials: Boolean): Array<AccountDetails?> {
return accountKeys.mapToArray { getDetails(it, getCredentials) }
}
fun AccountManager.getAllDetails(getCredentials: Boolean): Array<AccountDetails> {
return ownedAccounts.map { getDetailsOrThrow(it, getCredentials) }.sorted().toTypedArray()
}
fun isOfficial(context: Context, accountKey: UserKey): Boolean {
val am = AccountManager.get(context)
val account = am.findAccount(accountKey) ?: return false
return account.isOfficial(am, context)
}
val AccountManager.ownedAccounts: Array<Account> get() = getAccountsByType(ACCOUNT_TYPE)
private object API22 {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
internal fun removeAccount(
am: AccountManager, account: Account,
activity: Activity?,
@ -166,7 +212,7 @@ private object API22 {
}
private object API21 {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
internal fun renameAccount(am: AccountManager, account: Account,
newName: String,
callback: AccountManagerCallback<Account>?,

View File

@ -2,6 +2,7 @@ package org.mariotaku.twidere.extension.model
import android.content.Context
import org.mariotaku.microblog.library.twitter.annotation.MediaCategory
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.account.AccountExtras
@ -114,4 +115,22 @@ val Array<AccountDetails>.textLimit: Int
val AccountDetails.isStreamingSupported: Boolean
get() = type == AccountType.TWITTER
get() = type == AccountType.TWITTER
fun getAccountTypeIcon(@AccountType accountType: String?): Int {
when (accountType) {
AccountType.TWITTER -> {
return R.drawable.ic_account_logo_twitter
}
AccountType.FANFOU -> {
return R.drawable.ic_account_logo_fanfou
}
AccountType.STATUSNET -> {
return R.drawable.ic_account_logo_statusnet
}
AccountType.MASTODON -> {
return R.drawable.ic_account_logo_mastodon
}
}
return R.drawable.ic_account_logo_twitter
}

View File

@ -0,0 +1,31 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension.model
import org.mariotaku.ktextension.toString
import org.mariotaku.twidere.model.ParcelableLocation
val ParcelableLocation.isValid: Boolean
get() = !latitude.isNaN() && !longitude.isNaN()
fun ParcelableLocation.getHumanReadableString(decimalDigits: Int): String {
return String.format("%s,%s", latitude.toString(decimalDigits),
longitude.toString(decimalDigits))
}

View File

@ -36,7 +36,6 @@ import org.mariotaku.twidere.extension.model.updateContentFilterInfo
import org.mariotaku.twidere.extension.model.updateFilterInfo
import org.mariotaku.twidere.extension.toSpanItem
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.text.placeholder.CustomEmojiShortCodeSpan
import org.mariotaku.twidere.util.EntityArrays
@ -371,7 +370,7 @@ private val Status.parcelableLocation: ParcelableLocation?
get() {
val geoLocation = geoLocation
if (geoLocation != null) {
return ParcelableLocationUtils.fromGeoLocation(geoLocation)
return ParcelableLocation(geoLocation.latitude, geoLocation.longitude)
}
val locationString = location ?: return null
val location = ParcelableLocation.valueOf(locationString)

View File

@ -0,0 +1,49 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.extension.model.api.gnusocial
import org.mariotaku.microblog.library.statusnet.model.Group
import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.UserKey
fun Group.toParcelable(accountKey: UserKey, position: Int = -1, member: Boolean = false): ParcelableGroup {
val obj = ParcelableGroup()
obj.account_key = accountKey
obj.member = member
obj.position = position.toLong()
obj.id = id
obj.nickname = nickname
obj.homepage = homepage
obj.fullname = fullname
obj.url = url
obj.description = description
obj.location = location
obj.created = created?.time ?: -1
obj.modified = modified?.time ?: -1
obj.admin_count = adminCount
obj.member_count = memberCount
obj.original_logo = originalLogo
obj.homepage_logo = homepageLogo
obj.stream_logo = streamLogo
obj.mini_logo = miniLogo
obj.blocked = isBlocked
obj.id = id
return obj
}

View File

@ -79,7 +79,6 @@ import org.mariotaku.twidere.menu.AccountToggleProvider
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.SupportTabSpec
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
@ -749,7 +748,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
}
private fun loadAccountsInfo(loadFromDb: Boolean): AccountsInfo {
val accounts = AccountUtils.getAllAccountDetails(AccountManager.get(context), true)
val accounts = AccountManager.get(context).getAllDetails(true)
val draftsCount = if (loadFromDb) {
context.contentResolver.queryCount(Drafts.CONTENT_URI_UNSENT, null,
null)

View File

@ -60,6 +60,7 @@ import org.mariotaku.twidere.adapter.ArrayAdapter
import org.mariotaku.twidere.annotation.CustomTabType
import org.mariotaku.twidere.annotation.TabAccountFlags
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.insert
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.update
@ -68,7 +69,6 @@ import org.mariotaku.twidere.model.Tab
import org.mariotaku.twidere.model.tab.DrawableHolder
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.model.tab.iface.AccountCallback
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs
import org.mariotaku.twidere.util.CustomTabUtils
import org.mariotaku.twidere.util.ThemeUtils
@ -138,7 +138,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_custom_tabs, menu)
val context = this.context!!
val accounts = AccountUtils.getAllAccountDetails(AccountManager.get(context), false)
val accounts = AccountManager.get(context).getAllDetails(false)
val itemAdd = menu.findItem(R.id.add_submenu)
val theme = Chameleon.getOverrideTheme(context, context)
if (itemAdd != null && itemAdd.hasSubMenu()) {
@ -295,7 +295,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
accountsAdapter.add(AccountDetails.dummy())
}
val officialKeyOnly = arguments!!.getBoolean(EXTRA_OFFICIAL_KEY_ONLY, false)
accountsAdapter.addAll(AccountUtils.getAllAccountDetails(AccountManager.get(context), true).filter {
accountsAdapter.addAll(AccountManager.get(context).getAllDetails(true).filter {
if (officialKeyOnly && !it.isOfficial(context!!)) {
return@filter false
}

View File

@ -43,6 +43,7 @@ import org.mariotaku.twidere.annotation.LoadMorePosition
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.extension.accountKey
import org.mariotaku.twidere.extension.findAccount
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.extension.simpleLayout
@ -54,7 +55,6 @@ import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.BlockPromises
import org.mariotaku.twidere.promise.FriendshipPromises
import org.mariotaku.twidere.promise.MutePromises
@ -178,7 +178,7 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
adapter.showFollow = showFollow
val accountType = arguments?.accountKey?.let { key ->
val am = AccountManager.get(context)
return@let AccountUtils.findByAccountKey(am, key)?.getAccountType(am)
return@let am.findAccount(key)?.getAccountType(am)
}
when (accountType) {
AccountType.TWITTER, AccountType.FANFOU, AccountType.STATUSNET -> {

View File

@ -114,7 +114,6 @@ import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.model.event.FriendshipUpdatedEvent
import org.mariotaku.twidere.model.event.ProfileUpdatedEvent
import org.mariotaku.twidere.model.event.TaskStateChangedEvent
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.model.util.ParcelableRelationshipUtils
import org.mariotaku.twidere.promise.BlockPromises
@ -526,8 +525,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString())
}
val intent = Intent(Intent.ACTION_VIEW, builder.build())
intent.putExtra(EXTRA_ACCOUNT, AccountUtils.getAccountDetails(am, accountKey,
true))
intent.putExtra(EXTRA_ACCOUNT, am.getDetails(accountKey, true))
intent.putExtra(EXTRA_USERS, arrayOf(user))
intent.putExtra(EXTRA_OPEN_CONVERSATION, true)
startActivity(intent)
@ -1361,14 +1359,14 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
filtering = isFiltering
})
}
val details = AccountUtils.getAccountDetails(AccountManager.get(context),
accountKey, true) ?: return SingleResponse(MicroBlogException("No Account"))
if (details.type == AccountType.TWITTER) {
if (!accountKey.hasSameHost(user.key)) {
return SingleResponse.getInstance(ParcelableRelationshipUtils.create(user, isFiltering))
}
}
try {
val details = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
if (details.type == AccountType.TWITTER) {
if (!accountKey.hasSameHost(user.key)) {
return SingleResponse.getInstance(ParcelableRelationshipUtils.create(user, isFiltering))
}
}
val data = when (details.type) {
AccountType.MASTODON -> {
val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java)

View File

@ -44,7 +44,6 @@ import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.*
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.ParcelableActivitiesAdapter
@ -58,6 +57,7 @@ import org.mariotaku.twidere.constant.readFromBottomKey
import org.mariotaku.twidere.data.CursorObjectLivePagedListProvider
import org.mariotaku.twidere.data.CursorObjectLivePagedListProvider.CursorObjectProcessor
import org.mariotaku.twidere.data.ExtendedPagedListProvider
import org.mariotaku.twidere.extension.findAccount
import org.mariotaku.twidere.extension.model.activityStatus
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.extension.queryOne
@ -65,7 +65,10 @@ import org.mariotaku.twidere.extension.view.firstVisibleItemPosition
import org.mariotaku.twidere.extension.view.lastVisibleItemPosition
import org.mariotaku.twidere.fragment.AbsContentRecyclerViewFragment
import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.analyzer.Share
import org.mariotaku.twidere.model.event.FavoriteTaskEvent
import org.mariotaku.twidere.model.event.GetActivitiesTaskEvent
@ -74,7 +77,6 @@ import org.mariotaku.twidere.model.event.StatusRetweetedEvent
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.refresh.BaseContentRefreshParam
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.task.statuses.GetStatusesTask
import org.mariotaku.twidere.util.*
@ -190,7 +192,7 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
startActivity(chooser)
val am = AccountManager.get(context)
val accountType = AccountUtils.findByAccountKey(am, status.account_key)?.getAccountType(am)
val accountType = am.findAccount(status.account_key)?.getAccountType(am)
Analyzer.log(Share.status(accountType, status))
return true
}
@ -304,8 +306,10 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
}
}
if (firstVisiblePosition == 0 && !preferences[readFromBottomKey]) {
val weakThis by weak(this)
recyclerView.post {
scrollToStart()
val f = weakThis?.takeIf { !it.isDetached } ?: return@post
f.scrollToStart()
}
}
}
@ -509,14 +513,6 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
override fun onGapClick(holder: GapViewHolder, position: Int) {
val activity = adapter.getActivity(position)
DebugLog.v(msg = "Load activity gap $activity")
if (!AccountUtils.isOfficial(context!!, activity.account_key)) {
// Skip if item is not a status
if (activity.action !in Activity.Action.MENTION_ACTIONS) {
adapter.removeGapLoadingId(ObjectId(activity.account_key, activity.id))
adapter.notifyItemChanged(position)
return
}
}
val accountKeys = arrayOf(activity.account_key)
val pagination = arrayOf(SinceMaxPagination.maxId(activity.min_position,
activity.min_sort_position))

View File

@ -45,7 +45,6 @@ import org.mariotaku.twidere.extension.util.isAdvancedFiltersEnabled
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.model.filter.FilterScopesHolder
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
@ -116,8 +115,11 @@ class AddEditItemFragment : BaseDialogFragment() {
editText.setAdapter(when (contentUri) {
Filters.Sources.CONTENT_URI -> SourceAutoCompleteAdapter(activity!!)
Filters.Users.CONTENT_URI -> ComposeAutoCompleteAdapter(activity!!, requestManager).apply {
val am = AccountManager.get(activity)
account = AccountUtils.getDefaultAccountDetails(activity!!, am, false)
val accountKey = arguments!!.accountKey
if (accountKey != null) {
val am = AccountManager.get(activity)
account = am.getDetails(accountKey, false)
}
}
else -> null
})

View File

@ -34,17 +34,12 @@ import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_HOST
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.bulkDelete
import org.mariotaku.twidere.extension.dismissProgressDialog
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.showProgressDialog
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.fragment.AddUserFilterDialogFragment
import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.MutePromises
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.text.style.EmojiSpan
@ -218,8 +213,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
showProgressDialog("export_to_muted").then {
val context = weakThis?.context ?: throw InterruptedException()
val am = AccountManager.get(context)
val account = AccountUtils.getAccountDetails(am, accountKey, true) ?:
throw AccountNotFoundException()
val account = am.getDetailsOrThrow(accountKey, true)
MutePromises.muteUsers(context, account, items)
}.alwaysUi {
weakThis?.dismissProgressDialog("export_to_muted")

View File

@ -36,6 +36,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.extension.model.api.gnusocial.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.fragment.AbsToolbarTabPagesFragment
import org.mariotaku.twidere.fragment.timeline.GroupTimelineFragment
@ -43,7 +44,6 @@ import org.mariotaku.twidere.fragment.users.GroupMembersFragment
import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableGroupUtils
import org.mariotaku.twidere.util.Utils
/**
@ -142,8 +142,7 @@ class GroupFragment : AbsToolbarTabPagesFragment(), LoaderCallbacks<SingleRespon
} else {
return SingleResponse()
}
return SingleResponse.getInstance(ParcelableGroupUtils.from(group, accountKey, 0,
group.isMember))
return SingleResponse.getInstance(group.toParcelable(accountKey, member = group.isMember))
} catch (e: MicroBlogException) {
return SingleResponse(e)
}

View File

@ -57,6 +57,7 @@ import org.mariotaku.twidere.annotation.CacheFileType
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_POSITION
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.authorizationHeader
import org.mariotaku.twidere.extension.model.bannerExtras
import org.mariotaku.twidere.extension.model.getBestVideoUrlAndType
@ -72,7 +73,6 @@ import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.isMutedB
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.media
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.CacheProvider
import org.mariotaku.twidere.task.SaveFileTask
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
@ -109,7 +109,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
private var playerHasError: Boolean = false
private val account by lazy {
AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
AccountManager.get(context).getDetailsOrThrow(accountKey, true)
}
private val playerListener = object : Player.EventListener {

View File

@ -88,7 +88,6 @@ import org.mariotaku.twidere.fragment.message.MessageConversationInfoFragment.Co
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.ParcelableMessageConversation.ExtrasType
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.ConversationPromises
import org.mariotaku.twidere.promise.MessagePromises
import org.mariotaku.twidere.promise.UpdateStatusPromise
@ -432,8 +431,7 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
task {
val fragment = weakThis ?: throw InterruptedException()
val context = fragment.context ?: throw InterruptedException()
val account = AccountUtils.getAccountDetails(AccountManager.get(context),
accountKey, true) ?: throw MicroBlogException("No account")
val account = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
return@task updateAction(fragment, account, microBlog)
}.then { result ->

View File

@ -43,11 +43,8 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SelectableUsersAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.extension.accountKey
import org.mariotaku.twidere.extension.insert
import org.mariotaku.twidere.extension.linkHandlerTitle
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.queryOne
import org.mariotaku.twidere.extension.text.appendCompat
import org.mariotaku.twidere.fragment.BaseFragment
import org.mariotaku.twidere.loader.CacheUserSearchLoader
@ -55,7 +52,6 @@ import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
import org.mariotaku.twidere.task.twitter.message.SendMessageTask
import org.mariotaku.twidere.text.MarkForDeleteSpan
@ -63,15 +59,10 @@ import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.view.SimpleTextWatcher
import java.lang.ref.WeakReference
/**
* Created by mariotaku on 2017/2/15.
*/
class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks<List<ParcelableUser>?> {
private val accountKey by lazy { arguments!!.accountKey!! }
private val account by lazy {
AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
}
private val account by lazy { AccountManager.get(context).getDetails(accountKey, true) }
private var selectedRecipients: List<ParcelableUser>
get() {

View File

@ -78,7 +78,6 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
import org.mariotaku.twidere.model.event.SendMessageTaskEvent
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.MessagePromises
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
import org.mariotaku.twidere.service.LengthyOperationsService
@ -98,7 +97,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
private val conversationId: String get() = arguments!!.conversationId!!
private val account: AccountDetails? by lazy {
AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
AccountManager.get(context).getDetails(accountKey, true)
}
private val loadMoreTaskTag: String

View File

@ -53,7 +53,6 @@ import org.mariotaku.twidere.fragment.users.SearchUsersFragment
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.analyzer.Search
import org.mariotaku.twidere.model.tab.DrawableHolder
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.SavedSearchPromises
import org.mariotaku.twidere.provider.RecentSearchProvider
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory
@ -80,7 +79,7 @@ class SearchFragment : AbsToolbarTabPagesFragment(), RefreshScrollTopInterface,
private val accountType: String?
get() {
val am = AccountManager.get(context)
return accountKey.let { AccountUtils.findByAccountKey(am, it) }?.getAccountType(am)
return am.findAccount(accountKey)?.getAccountType(am)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {

View File

@ -45,7 +45,6 @@ import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.view.holder.status.StatusViewHolder
import java.lang.ref.WeakReference
@ -81,7 +80,7 @@ abstract class AbsStatusDialogFragment : BaseDialogFragment() {
it.applyTheme()
val am = AccountManager.get(context)
val details = AccountUtils.getAccountDetails(am, accountKey, true) ?: run {
val details = am.getDetails(accountKey, true) ?: run {
dismiss()
return@onShow
}

View File

@ -88,7 +88,6 @@ import org.mariotaku.twidere.model.event.FavoriteTaskEvent
import org.mariotaku.twidere.model.event.StatusListChangedEvent
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.CachedStatuses
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.AbsAccountRequestTask
@ -572,7 +571,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
startActivity(chooser)
val am = AccountManager.get(context)
val accountType = AccountUtils.findByAccountKey(am, status.account_key)?.getAccountType(am)
val accountType = am.findAccount(status.account_key)?.getAccountType(am)
Analyzer.log(Share.status(accountType, status))
return true

View File

@ -65,6 +65,7 @@ import org.mariotaku.twidere.data.ExtendedPagedListProvider
import org.mariotaku.twidere.data.StatusesLivePagedListProvider
import org.mariotaku.twidere.data.fetcher.StatusesFetcher
import org.mariotaku.twidere.extension.adapter.removeStatuses
import org.mariotaku.twidere.extension.findAccount
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.extension.promise
@ -90,7 +91,6 @@ import org.mariotaku.twidere.model.refresh.BaseContentRefreshParam
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.tab.extra.TimelineTabExtras
import org.mariotaku.twidere.model.timeline.TimelineFilter
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.StatusPromises
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.CreateFavoriteTask
@ -224,7 +224,7 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
startActivity(chooser)
val am = AccountManager.get(context)
val accountType = AccountUtils.findByAccountKey(am, status.account_key)?.getAccountType(am)
val accountType = am.findAccount(status.account_key)?.getAccountType(am)
Analyzer.log(Share.status(accountType, status))
return true
}
@ -341,7 +341,11 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
}
}
if (firstVisiblePosition == 0 && !preferences[readFromBottomKey]) {
scrollToStart()
val weakThis by weak(this)
recyclerView.post {
val f = weakThis?.takeIf { !it.isDetached } ?: return@post
f.scrollToStart()
}
}
}

View File

@ -28,12 +28,12 @@ import org.mariotaku.twidere.TwidereConstants.USER_TYPE_FANFOU_COM
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter
import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.extension.accountKey
import org.mariotaku.twidere.extension.isOfficial
import org.mariotaku.twidere.extension.linkHandlerTitle
import org.mariotaku.twidere.fragment.ParcelableUsersFragment
import org.mariotaku.twidere.loader.users.AbsRequestUsersLoader
import org.mariotaku.twidere.loader.users.IncomingFriendshipsLoader
import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.FriendshipPromises
import org.mariotaku.twidere.view.holder.UserViewHolder
@ -55,7 +55,7 @@ class IncomingFriendshipsFragment : ParcelableUsersFragment(), IUsersAdapter.Req
val accountKey = arguments?.accountKey ?: return adapter
if (USER_TYPE_FANFOU_COM == accountKey.host) {
adapter.requestClickListener = this
} else if (AccountUtils.isOfficial(context, accountKey)) {
} else if (isOfficial(context, accountKey)) {
adapter.requestClickListener = this
}
return adapter

View File

@ -5,9 +5,9 @@ import android.accounts.OnAccountsUpdateListener
import android.content.Context
import android.support.v4.content.FixedAsyncTaskLoader
import org.mariotaku.twidere.extension.addOnAccountsUpdatedListenerSafe
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.removeOnAccountsUpdatedListenerSafe
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
import java.lang.ref.WeakReference
/**
@ -31,7 +31,7 @@ class AccountDetailsLoader(
override fun loadInBackground(): List<AccountDetails> {
val am: AccountManager = AccountManager.get(context)
return AccountUtils.getAllAccountDetails(am, true).filter {
return am.getAllDetails(true).filter {
filter?.invoke(it) ?: true
}.sortedBy(AccountDetails::position)
}

View File

@ -26,12 +26,12 @@ import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.ListResponse
import org.mariotaku.twidere.model.ParcelableHashtag
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
class MastodonSearchLoader(
context: Context,
@ -42,9 +42,8 @@ class MastodonSearchLoader(
override fun loadInBackground(): List<Any> {
try {
val am = AccountManager.get(context)
val account = accountKey?.let {
AccountUtils.getAccountDetails(am, it, true)
} ?: throw AccountNotFoundException()
val key = accountKey ?: throw AccountNotFoundException()
val account = am.getDetailsOrThrow(key, true)
val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java)
val searchResult = mastodon.search(query, true, null)
return ListResponse(ArrayList<Any>().apply {

View File

@ -30,21 +30,19 @@ import org.mariotaku.restfu.http.RestHttpClient
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.updateExtraInformation
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.deleteActivityStatus
import org.mariotaku.twidere.util.deleteStatus
import javax.inject.Inject
/**
* Created by mariotaku on 14/12/5.
*/
class ParcelableStatusLoader(
context: Context,
private val omitIntentExtra: Boolean,
@ -66,7 +64,7 @@ class ParcelableStatusLoader(
if (accountKey == null || statusId == null) {
return SingleResponse(IllegalArgumentException())
}
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
val details = AccountManager.get(context).getDetails(accountKey, true)
if (!omitIntentExtra && extras != null) {
val cache: ParcelableStatus? = extras.getParcelable(IntentConstants.EXTRA_STATUS)
if (cache != null) {
@ -75,8 +73,8 @@ class ParcelableStatusLoader(
return response
}
}
if (details == null) return SingleResponse(MicroBlogException("No account"))
try {
if (details == null) throw AccountNotFoundException()
val status = DataStoreUtils.findStatus(context, accountKey, statusId)
status.updateExtraInformation(details)
val response = SingleResponse(status)

View File

@ -28,13 +28,13 @@ import org.mariotaku.microblog.library.statusnet.model.Group
import org.mariotaku.microblog.library.twitter.model.PageableResponseList
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.api.gnusocial.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.ParcelableGroupUtils
import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList
import java.util.*
@ -83,12 +83,12 @@ abstract class BaseGroupsLoader(
val dataSize = data.size
for (i in 0 until listSize) {
val group = listLoaded[i]
data.add(ParcelableGroupUtils.from(group, accountKey, dataSize + i, isMember(group)))
data.add(group.toParcelable(accountKey, dataSize + i, isMember(group)))
}
} else {
for (i in 0 until listSize) {
val list = listLoaded[i]
data.add(ParcelableGroupUtils.from(listLoaded[i], accountKey, i, isMember(list)))
data.add(listLoaded[i].toParcelable(accountKey, i, isMember(list)))
}
}
}

View File

@ -30,7 +30,9 @@ import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.api.applyLoadLimit
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.AccountDetails
@ -41,7 +43,6 @@ import org.mariotaku.twidere.model.pagination.PaginatedArrayList
import org.mariotaku.twidere.model.pagination.PaginatedList
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.task.statuses.GetStatusesTask
import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.UserColorNameManager
@ -90,9 +91,6 @@ abstract class AbsRequestStatusesLoader(
override final fun loadInBackground(): ListResponse<ParcelableStatus> {
val context = context
val comparator = this.comparator
val accountKey = accountKey ?: return ListResponse.getListInstance<ParcelableStatus>(MicroBlogException("No Account"))
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?:
return ListResponse.getListInstance<ParcelableStatus>(MicroBlogException("No Account"))
if (!fromUser) {
data.forEach { it.is_filtered = shouldFilterStatus(it) }
@ -101,10 +99,12 @@ abstract class AbsRequestStatusesLoader(
val noItemsBefore = data.isEmpty()
val loadItemLimit = preferences[loadItemLimitKey]
val statuses = try {
val accountKey = accountKey ?: throw AccountNotFoundException()
val account = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val paging = Paging().apply {
processPaging(this, details, loadItemLimit)
processPaging(this, account, loadItemLimit)
}
getStatuses(details, paging)
getStatuses(account, paging)
} catch (e: MicroBlogException) {
// mHandler.post(new ShowErrorRunnable(e));
exception = e

View File

@ -35,6 +35,7 @@ import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.loader.iface.IPaginationLoader
@ -42,7 +43,6 @@ import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList
import java.util.*
import javax.inject.Inject
@ -82,7 +82,7 @@ abstract class BaseUserListsLoader(
var listLoaded: List<UserList>? = null
try {
val am = AccountManager.get(context)
val details = AccountUtils.getAccountDetails(am, accountKey, true) ?: return data
val details = am.getDetails(accountKey, true) ?: return data
val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java)
val paging = Paging()
paging.count(preferences[loadItemLimitKey].coerceIn(0, 100))

View File

@ -28,6 +28,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.api.applyLoadLimit
import org.mariotaku.twidere.loader.iface.IPaginationLoader
import org.mariotaku.twidere.model.AccountDetails
@ -36,7 +37,6 @@ import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.PaginatedList
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.DebugLog
import java.util.*
@ -65,9 +65,8 @@ abstract class AbsRequestUsersLoader(
val details: AccountDetails
val users: List<ParcelableUser>
try {
val am = AccountManager.get(context)
details = accountKey?.let { AccountUtils.getAccountDetails(am, it, true) } ?:
throw AccountNotFoundException()
val accountKey = accountKey ?: throw AccountNotFoundException()
details = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
users = getUsersInternal(details)
} catch (e: MicroBlogException) {
DebugLog.w(tr = e)

View File

@ -8,13 +8,13 @@ import android.view.Menu
import android.view.SubMenu
import org.mariotaku.twidere.TwidereConstants
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
class AccountActionProvider(
context: Context,
var accounts: Array<AccountDetails>? = AccountUtils.getAllAccountDetails(AccountManager.get(context), false)
var accounts: Array<AccountDetails>? = AccountManager.get(context).getAllDetails(false)
) : ActionProvider(context), TwidereConstants {
var selectedAccountKeys: Array<UserKey>? = null

View File

@ -32,7 +32,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
import org.mariotaku.twidere.constant.defaultAutoRefreshKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.extension.getDetails
class AccountPreferences(
private val context: Context,
@ -43,7 +43,7 @@ class AccountPreferences(
val defaultNotificationLightColor: Int
get() {
val a = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)
val a = AccountManager.get(context).getDetails(accountKey, true)
if (a != null) {
return a.color
} else {

View File

@ -29,6 +29,7 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.TabAccountFlags
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_MENTIONS_ONLY
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_MY_FOLLOWING_ONLY
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.fragment.activities.InteractionsActivitiesFragment
import org.mariotaku.twidere.model.AccountDetails
@ -39,7 +40,6 @@ import org.mariotaku.twidere.model.tab.StringHolder
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.model.tab.conf.BooleanExtraConfiguration
import org.mariotaku.twidere.model.tab.extra.InteractionsTabExtras
import org.mariotaku.twidere.model.util.AccountUtils
/**
* Created by mariotaku on 2016/11/27.
@ -103,7 +103,7 @@ class InteractionsTabConfiguration : TabConfiguration() {
if (account == null || account.dummy) {
val am = AccountManager.get(context)
val accounts = AccountUtils.getAllAccountDetails(am, false)
val accounts = am.getAllDetails(false)
interactionsAvailable = accounts.any { it.supportsInteractions }
requiresStreaming = accounts.all { it.requiresStreaming }
} else when (account.type) {

View File

@ -4,6 +4,7 @@ import android.accounts.AccountManager
import android.content.Context
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.extension.model.unique_id_non_null
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.ParcelableStatusUpdate
@ -20,7 +21,7 @@ object ParcelableStatusUpdateUtils {
fun fromDraftItem(context: Context, draft: Draft): ParcelableStatusUpdate {
val statusUpdate = ParcelableStatusUpdate()
statusUpdate.accounts = draft.account_keys?.let {
AccountUtils.getAllAccountDetails(AccountManager.get(context), it, true)
AccountManager.get(context).getAllDetails(it, true)
} ?: emptyArray()
statusUpdate.text = draft.text
statusUpdate.location = draft.location

View File

@ -37,8 +37,8 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getAllDetails
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.media.MediaPreloader
import javax.inject.Inject
@ -69,7 +69,7 @@ abstract class AccountsListPreference(context: Context, attrs: AttributeSet? = n
override final fun onAttachedToHierarchy(preferenceManager: PreferenceManager) {
super.onAttachedToHierarchy(preferenceManager)
if (preferenceCount > 0) return
setAccountsData(AccountUtils.getAllAccountDetails(AccountManager.get(context), true))
setAccountsData(AccountManager.get(context).getAllDetails(true))
}
protected open fun getSwitchDefault(): Boolean {

View File

@ -28,7 +28,6 @@ import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.addParticipants
import org.mariotaku.twidere.extension.model.isOfficial
@ -38,7 +37,6 @@ import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.lang.ApplicationContextSingletonHolder
@ -49,8 +47,7 @@ class ConversationPromises private constructor(private val application: Applicat
fun setNotificationDisabled(accountKey: UserKey, conversationId: String,
notificationDisabled: Boolean): Promise<Boolean, Exception> = task {
val account = AccountUtils.getAccountDetails(AccountManager.get(application),
accountKey, true) ?: throw AccountNotFoundException()
val account = AccountManager.get(application).getDetailsOrThrow(accountKey, true)
val addData = requestSetNotificationDisabled(account, conversationId, notificationDisabled)
GetMessagesTask.storeMessages(application, addData, account)
return@task true

View File

@ -35,12 +35,12 @@ import org.mariotaku.twidere.constant.homeRefreshSavedSearchesKey
import org.mariotaku.twidere.dagger.component.GeneralComponent
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.isOfficial
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.promise
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.statuses.GetHomeTimelineTask
@ -113,7 +113,7 @@ class RefreshPromises private constructor(val application: Context) {
for (accountKey in accountKeys) {
val microBlog = AccountManager.get(application).getDetailsOrThrow(accountKey, true)
.newMicroBlogInstance(application, MicroBlog::class.java)
if (!AccountUtils.isOfficial(application, accountKey)) continue
if (!isOfficial(application, accountKey)) continue
microBlog.setActivitiesAboutMeUnread(cursor)
}
}

View File

@ -47,10 +47,7 @@ import org.mariotaku.microblog.library.fanfou.model.PhotoStatusUpdate
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.microblog.library.mastodon.model.Attachment
import org.mariotaku.microblog.library.twitter.TwitterUpload
import org.mariotaku.microblog.library.twitter.model.ErrorInfo
import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse
import org.mariotaku.microblog.library.twitter.model.NewMediaMetadata
import org.mariotaku.microblog.library.twitter.model.StatusUpdate
import org.mariotaku.microblog.library.twitter.model.*
import org.mariotaku.restfu.http.ContentType
import org.mariotaku.restfu.http.mime.Body
import org.mariotaku.restfu.http.mime.FileBody
@ -72,7 +69,6 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.account.AccountExtras
import org.mariotaku.twidere.model.analyzer.UpdateStatus
import org.mariotaku.twidere.model.schedule.ScheduleInfo
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.preference.ComponentPickerPreference
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.util.*
@ -461,8 +457,9 @@ class UpdateStatusPromise(
if (statusUpdate.attachment_url != null) {
status.attachmentUrl(statusUpdate.attachment_url)
}
if (statusUpdate.location != null) {
status.location(ParcelableLocationUtils.toGeoLocation(statusUpdate.location))
val location = statusUpdate.location
if (location != null) {
status.location(GeoLocation(location.latitude, location.longitude))
status.displayCoordinates(statusUpdate.display_coordinates)
}
val mediaIds = pendingUpdate.mediaIds[index]

View File

@ -50,17 +50,13 @@ import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.constant.refreshAfterTweetKey
import org.mariotaku.twidere.extension.get
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.extension.model.notificationBuilder
import org.mariotaku.twidere.extension.queryOne
import org.mariotaku.twidere.extension.withAppendedPath
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras
import org.mariotaku.twidere.model.draft.StatusObjectActionExtras
import org.mariotaku.twidere.model.notification.NotificationChannelSpec
import org.mariotaku.twidere.model.schedule.ScheduleInfo
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
import org.mariotaku.twidere.promise.RefreshPromises
import org.mariotaku.twidere.promise.UpdateStatusPromise
@ -136,7 +132,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
val message = ParcelableNewMessage().apply {
this.account = draft.account_keys?.firstOrNull()?.let { key ->
val am = AccountManager.get(this@LengthyOperationsService)
return@let AccountUtils.getAccountDetails(am, key, true)
return@let am.getDetails(key, true)
}
this.text = draft.text
this.media = draft.media

View File

@ -38,7 +38,6 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.notification.NotificationChannelSpec
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.task.twitter.GetActivitiesAboutMeTask
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
@ -138,7 +137,7 @@ class StreamingService : BaseService() {
private fun updateStreamingInstances(): Boolean {
val am = AccountManager.get(this)
val supportedAccounts = AccountUtils.getAllAccountDetails(am, true).filter { it.isStreamingSupported }
val supportedAccounts = am.getAllDetails(true).filter { it.isStreamingSupported }
val supportedPrefs = supportedAccounts.map { AccountPreferences(this, preferences, it.key) }
val enabledAccounts = supportedAccounts.filter { account ->
return@filter supportedPrefs.any {

View File

@ -27,13 +27,13 @@ import org.mariotaku.ktextension.toLongOr
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.delete
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.insert
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.ObjectId
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.promise.UpdateStatusPromise
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
@ -42,9 +42,8 @@ abstract class AbsAccountRequestTask<Params, Result, Callback>(context: Context,
override final val exceptionClass = MicroBlogException::class.java
override final fun onExecute(params: Params): Result {
val am = AccountManager.get(context)
val account = accountKey?.let { AccountUtils.getAccountDetails(am, it, true) } ?:
throw AccountNotFoundException()
if (accountKey == null) throw AccountNotFoundException()
val account = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val draft = createDraft()
var draftId = -1L
if (draft != null) {

View File

@ -43,8 +43,8 @@ import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.data.fetcher.StatusesFetcher
import org.mariotaku.twidere.data.syncher.TimelinePositionSyncher
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.bulkInsert
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.applyLoadLimit
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
@ -56,7 +56,6 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetStatusesTaskEvent
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.task.GetTimelineResult
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.AccountSupportColumns
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.BaseAbstractTask
@ -85,8 +84,7 @@ abstract class GetStatusesTask<P : ContentRefreshParam>(
val loadItemLimit = preferences[loadItemLimitKey]
val result = accountKeys.mapIndexed { i, accountKey ->
try {
val account = AccountUtils.getAccountDetails(AccountManager.get(context),
accountKey, true) ?: throw AccountNotFoundException()
val account = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val paging = Paging()
paging.applyLoadLimit(account, loadItemLimit)
val maxId = param.getMaxId(i)

View File

@ -21,9 +21,9 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.FilterScope
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.data.fetcher.ActivitiesFetcher
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.api.batchGetRelationships
import org.mariotaku.twidere.extension.bulkInsert
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
@ -33,7 +33,6 @@ import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetActivitiesTaskEvent
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.task.GetTimelineResult
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.task.BaseAbstractTask
import org.mariotaku.twidere.task.statuses.GetStatusesTask
@ -65,8 +64,7 @@ abstract class GetActivitiesTask(
val loadItemLimit = preferences[loadItemLimitKey]
val result = accountKeys.mapIndexed { i, accountKey ->
val noItemsBefore = DataStoreUtils.getActivitiesCount(context, contentUri, accountKey) <= 0
val credentials = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey,
true) ?: throw AccountNotFoundException()
val credentials = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val paging = Paging()
paging.count(loadItemLimit)
val maxId = param.getMaxId(i)

View File

@ -23,7 +23,6 @@ import android.accounts.AccountManager
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.ktextension.toIntOr
import org.mariotaku.ktextension.toLongOr
@ -37,11 +36,9 @@ import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_SHOW_NOTIFICATION
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.blockBulkInsert
import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.queryCount
import org.mariotaku.twidere.extension.queryReference
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
@ -51,8 +48,6 @@ import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.refresh.ContentRefreshParam
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
@ -77,11 +72,7 @@ class GetMessagesTask(
val accountKeys = param.accountKeys
val am = android.accounts.AccountManager.get(context)
accountKeys.forEachIndexed { i, accountKey ->
val details = try {
getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
} catch (e: LoganSquareMapperFinder.ClassLoaderDeadLockException) {
return
}
val details = am.getDetails(accountKey, true) ?: return@forEachIndexed
val microBlog = details.newMicroBlogInstance(context, cls = MicroBlog::class.java)
val messages = try {
getMessages(microBlog, details, param, i)
@ -346,7 +337,7 @@ class GetMessagesTask(
var taskTag: String? = null
protected val accounts: Array<AccountDetails?> by lazy {
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
AccountManager.get(context).getAllDetails(accountKeys, false)
}
protected val defaultKeys: Array<UserKey?> by lazy {

View File

@ -1,21 +1,17 @@
package org.mariotaku.twidere.text
import android.text.SpannableString
import org.mariotaku.ktextension.fixSHY
import org.mariotaku.twidere.util.CheckUtils
import org.mariotaku.twidere.util.TwidereStringUtils
/**
* Created by Ningyuan on 2015/5/1.
*/
class SafeSpannableString(source: CharSequence) : SpannableString(source) {
init {
TwidereStringUtils.fixSHY(this)
fixSHY()
}
override fun setSpan(what: Any, start: Int, end: Int, flags: Int) {
if (!CheckUtils.checkRange(this, start, end)) {
val validRange = 0..length
if (end < start || start !in validRange || end !in validRange) {
// Silently ignore
return
}

View File

@ -1,21 +1,17 @@
package org.mariotaku.twidere.text
import android.text.SpannableStringBuilder
import org.mariotaku.ktextension.fixSHY
import org.mariotaku.twidere.util.CheckUtils
import org.mariotaku.twidere.util.TwidereStringUtils
/**
* Created by Ningyuan on 2015/5/1.
*/
class SafeSpannableStringBuilder(source: CharSequence) : SpannableStringBuilder(source) {
init {
TwidereStringUtils.fixSHY(this)
fixSHY()
}
override fun setSpan(what: Any, start: Int, end: Int, flags: Int) {
if (!CheckUtils.checkRange(this, start, end)) {
val validRange = 0..length
if (end < start || start !in validRange || end !in validRange) {
// Silently ignore
return
}

View File

@ -16,7 +16,6 @@ import org.mariotaku.twidere.model.account.cred.BasicCredentials
import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.model.account.cred.EmptyCredentials
import org.mariotaku.twidere.model.account.cred.OAuthCredentials
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts
/**
@ -101,16 +100,27 @@ private fun ParcelableCredentials.toCredentials(): Credentials {
}
fun generateAccountName(screenName: String, accountHost: String?): String {
return UserKey(screenName, accountHost).toString()
}
@Credentials.Type
@Suppress("deprecation")
private fun ParcelableCredentials.getCredentialsType(): String {
return AccountUtils.getCredentialsType(auth_type)
return getCredentialsType(auth_type)
}
@Suppress("deprecation")
private val ParcelableCredentials.account_name: String
get() = generateAccountName(screen_name, account_key.host)
fun generateAccountName(screenName: String, accountHost: String?): String {
return UserKey(screenName, accountHost).toString()
private fun getCredentialsType(@AuthTypeInt authType: Int): String {
when (authType) {
AuthTypeInt.OAUTH -> return Credentials.Type.OAUTH
AuthTypeInt.BASIC -> return Credentials.Type.BASIC
AuthTypeInt.TWIP_O_MODE -> return Credentials.Type.EMPTY
AuthTypeInt.XAUTH -> return Credentials.Type.XAUTH
AuthTypeInt.OAUTH2 -> return Credentials.Type.OAUTH2
}
throw UnsupportedOperationException()
}

View File

@ -20,7 +20,6 @@
package org.mariotaku.twidere.util
import android.content.ContentValues
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.microblog.library.twitter.model.SavedSearch
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableUser

View File

@ -55,7 +55,6 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.tab.extra.HomeTabExtras
import org.mariotaku.twidere.model.tab.extra.InteractionsTabExtras
import org.mariotaku.twidere.model.tab.extra.TabExtras
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
@ -273,14 +272,13 @@ object DataStoreUtils {
fun getAccountName(context: Context, accountKey: UserKey): String? {
val am = AccountManager.get(context)
val account = AccountUtils.findByAccountKey(am, accountKey) ?: return null
val account = am.findAccount(accountKey) ?: return null
return account.getAccountUser(am).name
}
fun getAccountScreenName(context: Context, accountKey: UserKey): String? {
val am = AccountManager.get(context)
val account = AccountUtils.findByAccountKey(am, accountKey) ?: return null
val account = am.findAccount(accountKey) ?: return null
return account.getAccountUser(am).screen_name
}
@ -517,7 +515,7 @@ object DataStoreUtils {
val am = AccountManager.get(context)
val colors = IntArray(accountKeys.size)
for (i in accountKeys.indices) {
val account = AccountUtils.findByAccountKey(am, accountKeys[i])
val account = am.findAccount(accountKeys[i])
if (account != null) {
colors[i] = account.getColor(am)
}
@ -841,8 +839,7 @@ object DataStoreUtils {
val cached = findStatusInDatabases(context, accountKey, statusId)
val profileImageSize = context.getString(R.string.profile_image_size)
if (cached != null) return cached
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey,
true) ?: throw MicroBlogException("No account")
val details = AccountManager.get(context).getDetailsOrThrow(accountKey, true)
val status = when (details.type) {
AccountType.MASTODON -> {
val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java)
@ -883,14 +880,14 @@ object DataStoreUtils {
mergeResult: (T, T) -> T, accountKeys: Array<UserKey?>): T {
val officialKeys = Array(accountKeys.size) {
val key = accountKeys[it] ?: return@Array null
if (AccountUtils.isOfficial(context, key)) {
if (isOfficial(context, key)) {
return@Array key
}
return@Array null
}
val notOfficialKeys = Array(accountKeys.size) {
val key = accountKeys[it] ?: return@Array null
if (AccountUtils.isOfficial(context, key)) {
if (isOfficial(context, key)) {
return@Array null
}
return@Array key

View File

@ -24,7 +24,6 @@ import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.chromeCustomTabKey
import org.mariotaku.twidere.fragment.SensitiveContentWarningDialogFragment
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.util.LinkCreator.getTwidereUserListRelatedLink
import java.util.*
@ -276,7 +275,6 @@ object IntentUtils {
}
fun openMap(context: Context, latitude: Double, longitude: Double) {
if (!ParcelableLocationUtils.isValidLocation(latitude, longitude)) return
val builder = UriBuilder(AUTHORITY_MAP)
builder.appendQueryParameter(QUERY_PARAM_LAT, latitude.toString())
builder.appendQueryParameter(QUERY_PARAM_LNG, longitude.toString())

View File

@ -54,6 +54,7 @@ import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.constant.favoriteConfirmationKey
import org.mariotaku.twidere.constant.iWantMyStarsBackKey
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.promise
import org.mariotaku.twidere.fragment.AddStatusFilterDialogFragment
@ -67,7 +68,6 @@ import org.mariotaku.twidere.menu.FavoriteItemProvider
import org.mariotaku.twidere.menu.SupportStatusShareProvider
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.task.CreateFavoriteTask
import org.mariotaku.twidere.task.DestroyFavoriteTask
import org.mariotaku.twidere.task.DestroyStatusTask
@ -104,8 +104,7 @@ object MenuUtils {
fun setupForStatus(context: Context, menu: Menu, preferences: SharedPreferences,
manager: UserColorNameManager, status: ParcelableStatus) {
val account = AccountUtils.getAccountDetails(AccountManager.get(context),
status.account_key, true) ?: return
val account = AccountManager.get(context).getDetails(status.account_key, true) ?: return
setupForStatus(context, menu, preferences, manager, status, account)
}

View File

@ -56,7 +56,7 @@ import android.view.accessibility.AccessibilityManager
import android.widget.Toast
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.getNullableTypedArray
import org.mariotaku.ktextension.toLocalizedString
import org.mariotaku.ktextension.toString
import org.mariotaku.pickncrop.library.PNCUtils
import org.mariotaku.sqliteqb.library.AllColumns
import org.mariotaku.sqliteqb.library.Columns
@ -81,11 +81,11 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
import org.mariotaku.twidere.constant.bandwidthSavingModeKey
import org.mariotaku.twidere.constant.defaultAccountKey
import org.mariotaku.twidere.constant.mediaPreviewKey
import org.mariotaku.twidere.extension.findAccount
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableUserMention
import org.mariotaku.twidere.model.PebbleMessage
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.TwidereLinkify.PATTERN_TWITTER_PROFILE_IMAGES
import java.io.File
@ -285,7 +285,7 @@ object Utils {
}
fun getLocalizedNumber(locale: Locale, number: Number): String {
return number.toLocalizedString(locale)
return number.toString(locale)
}
fun getMatchedNicknameKeys(str: String, manager: UserColorNameManager): Array<String> {
@ -404,12 +404,12 @@ object Utils {
fun isMyAccount(context: Context, accountKey: UserKey): Boolean {
val am = AccountManager.get(context)
return AccountUtils.findByAccountKey(am, accountKey) != null
return am.findAccount(accountKey) != null
}
fun isMyAccount(context: Context, screenName: String): Boolean {
val am = AccountManager.get(context)
return AccountUtils.findByScreenName(am, screenName) != null
return am.findAccount(screenName) != null
}
fun isMyRetweet(status: ParcelableStatus?): Boolean {

View File

@ -26,12 +26,12 @@ import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.*
import okhttp3.OkHttpClient
import org.mariotaku.twidere.extension.findAccount
import org.mariotaku.twidere.extension.model.authorizationHeader
import org.mariotaku.twidere.extension.model.getCredentials
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.model.media.AuthenticatedUri
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
import java.io.InputStream
@ -50,10 +50,11 @@ class AuthenticatedUriLoader(
return OkHttpStreamFetcher(client, glideUrl)
}
val UserKey.credentials: Credentials? get() {
val am = AccountManager.get(context)
return AccountUtils.findByAccountKey(am, this)?.getCredentials(am)
}
val UserKey.credentials: Credentials?
get() {
val am = AccountManager.get(context)
return am.findAccount(this)?.getCredentials(am)
}
internal class AuthorizationHeaderFactory(val uri: Uri, val credentials: Credentials) : LazyHeaderFactory {
override fun buildHeader() = credentials.authorizationHeader(uri)

View File

@ -47,6 +47,7 @@ import org.mariotaku.twidere.annotation.NotificationType
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.iWantMyStarsBackKey
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.formattedTextWithIndices
import org.mariotaku.twidere.extension.queryOne
@ -54,7 +55,6 @@ import org.mariotaku.twidere.extension.queryReference
import org.mariotaku.twidere.extension.rawQuery
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.notification.NotificationChannelSpec
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
@ -169,7 +169,7 @@ class ContentNotificationManager(
val am = AccountManager.get(context)
val cr = context.contentResolver
val accountKey = pref.accountKey
val account = AccountUtils.getAccountDetails(am, accountKey, false) ?: return
val account = am.getDetails(accountKey, false) ?: return
val selection = Expression.and(
Expression.equalsArgs(Activities.ACCOUNT_KEY),
Expression.greaterThan(Activities.POSITION_KEY, position),

View File

@ -29,11 +29,11 @@ import android.os.Build
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.notificationChannelGroupId
import org.mariotaku.twidere.extension.model.notificationChannelId
import org.mariotaku.twidere.extension.ownedAccounts
import org.mariotaku.twidere.model.notification.NotificationChannelSpec
import org.mariotaku.twidere.model.util.AccountUtils
/**
* Created by mariotaku on 2017/8/25.
@ -92,11 +92,7 @@ object NotificationChannelsManager {
val addedGroups = mutableListOf<String>()
accounts.forEach { account ->
val details = try {
AccountUtils.getAccountDetails(am, account, false)
} catch (e: Exception) {
return@forEach
}
val details = am.getDetails(account, false) ?: return@forEach
val group = NotificationChannelGroup(details.key.notificationChannelGroupId(),
ucnm.getDisplayName(details.user, pref[nameFirstKey]))

View File

@ -38,11 +38,10 @@ import org.mariotaku.ktextension.weak
import org.mariotaku.microblog.library.twitter.TwitterCaps
import org.mariotaku.microblog.library.twitter.model.CardDataMap
import org.mariotaku.twidere.R
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.getDetailsOrThrow
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.model.ParcelableCardEntity
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.MicroBlogAPIFactory
import org.mariotaku.twidere.util.TwitterCardUtils
import org.mariotaku.twidere.util.support.ViewSupport
@ -91,8 +90,7 @@ class CardPollViewController : ContainerView.ViewController() {
val weakThis by weak(this)
task {
val vc = weakThis ?: throw IllegalStateException()
val details = AccountUtils.getAccountDetails(AccountManager.get(vc.context),
card.account_key, true) ?: throw AccountNotFoundException()
val details = AccountManager.get(vc.context).getDetailsOrThrow(card.account_key, true)
val caps = details.newMicroBlogInstance(vc.context, cls = TwitterCaps::class.java)
val params = CardDataMap()
params.putString("card_uri", card.url)
@ -187,8 +185,7 @@ class CardPollViewController : ContainerView.ViewController() {
val weakThis by weak(this)
task {
val vc = weakThis ?: throw InterruptedException()
val details = AccountUtils.getAccountDetails(AccountManager.get(vc.context),
card.account_key, true) ?: throw AccountNotFoundException()
val details = AccountManager.get(vc.context).getDetailsOrThrow(card.account_key, true)
val caps = details.newMicroBlogInstance(vc.context, cls = TwitterCaps::class.java)
val cardEntity = caps.sendPassThrough(cardData).card
return@task cardEntity.toParcelable(card.account_key, details.type)

View File

@ -28,8 +28,8 @@ import org.mariotaku.ktextension.spannable
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.AccountDetailsAdapter
import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.extension.model.getAccountTypeIcon
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.view.ProfileImageView
import org.mariotaku.twidere.view.iface.IColorLabelView
@ -66,7 +66,7 @@ class AccountViewHolder(
profileImage.visibility = View.VISIBLE
adapter.requestManager.loadProfileImage(adapter.context, details, adapter.profileImageStyle,
profileImage.cornerRadius, profileImage.cornerRadiusRatio).into(profileImage)
accountType.setImageResource(AccountUtils.getAccountTypeIcon(details.type))
accountType.setImageResource(getAccountTypeIcon(details.type))
toggle.setOnCheckedChangeListener(null)
toggle.isChecked = details.activated
toggle.setOnCheckedChangeListener(adapter.checkedChangeListener)

View File

@ -24,7 +24,6 @@ import android.view.View
import kotlinx.android.synthetic.main.card_item_group_compact.view.*
import org.mariotaku.ktextension.hideIfEmpty
import org.mariotaku.ktextension.spannable
import org.mariotaku.ktextension.toLocalizedString
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter
import org.mariotaku.twidere.extension.loadProfileImage
@ -77,8 +76,8 @@ class GroupViewHolder(private val adapter: IGroupsAdapter<*>, itemView: View) :
}
descriptionView.spannable = formatter.unicodeWrap(group.description)
descriptionView.hideIfEmpty()
membersCountView.text = group.member_count.toLocalizedString()
adminsCountView.text = group.admin_count.toLocalizedString()
membersCountView.text = group.member_count.toString()
adminsCountView.text = group.admin_count.toString()
}
fun setOnClickListeners() {

View File

@ -41,10 +41,7 @@ import android.view.ViewGroup
import kotlinx.android.synthetic.main.adapter_item_status_count_label.view.*
import kotlinx.android.synthetic.main.header_status.view.*
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.applyFontFamily
import org.mariotaku.ktextension.hideIfEmpty
import org.mariotaku.ktextension.spannable
import org.mariotaku.ktextension.supportActionProvider
import org.mariotaku.ktextension.*
import org.mariotaku.microblog.library.twitter.model.TranslationResult
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R
@ -60,7 +57,6 @@ import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment
import org.mariotaku.twidere.menu.FavoriteItemProvider
import org.mariotaku.twidere.menu.RetweetItemProvider
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.twitter.card.StatusCardViewFactory
@ -263,14 +259,14 @@ class DetailStatusViewHolder(
}
textView.hideIfEmpty()
val location: ParcelableLocation? = status.location
val placeFullName: String? = status.place_full_name
val location = status.location
val placeFullName = status.place_full_name
if (!TextUtils.isEmpty(placeFullName)) {
if (placeFullName != null && placeFullName.isNotEmpty()) {
locationView.visibility = View.VISIBLE
locationView.spannable = placeFullName
locationView.isClickable = ParcelableLocationUtils.isValidLocation(location)
} else if (ParcelableLocationUtils.isValidLocation(location)) {
locationView.isClickable = location != null && location.isValid
} else if (location != null && location.isValid) {
locationView.visibility = View.VISIBLE
locationView.setText(R.string.action_view_map)
locationView.isClickable = true
@ -297,22 +293,26 @@ class DetailStatusViewHolder(
val media = status.media
if (media?.isEmpty() != false) {
itemView.mediaPreviewContainer.visibility = View.GONE
itemView.mediaPreview.visibility = View.GONE
itemView.mediaPreviewLoad.visibility = View.GONE
itemView.mediaPreview.displayMedia()
} else if (adapter.isDetailMediaExpanded) {
itemView.mediaPreviewContainer.visibility = View.VISIBLE
itemView.mediaPreview.visibility = View.VISIBLE
itemView.mediaPreviewLoad.visibility = View.GONE
itemView.mediaPreview.displayMedia(adapter.requestManager, media = media,
accountKey = status.account_key, mediaClickListener = adapter.fragment)
} else {
itemView.mediaPreviewContainer.visibility = View.VISIBLE
itemView.mediaPreview.visibility = View.GONE
itemView.mediaPreviewLoad.visibility = View.VISIBLE
itemView.mediaPreview.displayMedia()
when {
media.isNullOrEmpty() -> {
itemView.mediaPreviewContainer.visibility = View.GONE
itemView.mediaPreview.visibility = View.GONE
itemView.mediaPreviewLoad.visibility = View.GONE
itemView.mediaPreview.displayMedia()
}
adapter.isDetailMediaExpanded -> {
itemView.mediaPreviewContainer.visibility = View.VISIBLE
itemView.mediaPreview.visibility = View.VISIBLE
itemView.mediaPreviewLoad.visibility = View.GONE
itemView.mediaPreview.displayMedia(adapter.requestManager, media = media,
accountKey = status.account_key, mediaClickListener = adapter.fragment)
}
else -> {
itemView.mediaPreviewContainer.visibility = View.VISIBLE
itemView.mediaPreview.visibility = View.GONE
itemView.mediaPreviewLoad.visibility = View.VISIBLE
itemView.mediaPreview.displayMedia()
}
}
if (TwitterCardUtils.isCardSupported(status)) {
@ -341,7 +341,7 @@ class DetailStatusViewHolder(
val lang = status.lang
if (CheckUtils.isValidLocale(lang) && account.isOfficial(context)) {
if (lang != null && lang.isValidLocale && account.isOfficial(context)) {
translateContainer.visibility = View.VISIBLE
if (translation != null) {
val locale = Locale(translation.translatedLang)
@ -395,8 +395,7 @@ class DetailStatusViewHolder(
}
}
locationView -> {
val location = status.location
if (!ParcelableLocationUtils.isValidLocation(location)) return
val location = status.location?.takeIf { it.isValid } ?: return
IntentUtils.openMap(adapter.context, location.latitude, location.longitude)
}
itemView.quotedView -> {
@ -801,5 +800,8 @@ class DetailStatusViewHolder(
const val REQUEST_FAVORITE_SELECT_ACCOUNT = 101
const val REQUEST_RETWEET_SELECT_ACCOUNT = 102
private val String.isValidLocale: Boolean
get() = !isEmpty() && this != "und"
}
}

View File

@ -30,7 +30,6 @@ import kotlinx.android.synthetic.main.adapter_item_large_media_status_preview_it
import org.mariotaku.ktextension.applyFontFamily
import org.mariotaku.ktextension.hideIfEmpty
import org.mariotaku.ktextension.spannable
import org.mariotaku.ktextension.toLocalizedString
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.RecyclerPagerAdapter
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter
@ -124,15 +123,15 @@ class LargeMediaStatusViewHolder(private val adapter: IStatusesAdapter, itemView
if (status.favorite_count > 0) {
if (adapter.useStarsForLikes) {
countsTexts.add(context.resources.getQuantityString(R.plurals.N_favorites_abbrev,
status.favorite_count.toInt(), status.favorite_count.toLocalizedString()))
status.favorite_count.toInt(), status.favorite_count.toString()))
} else {
countsTexts.add(context.resources.getQuantityString(R.plurals.N_likes_abbrev,
status.favorite_count.toInt(), status.favorite_count.toLocalizedString()))
status.favorite_count.toInt(), status.favorite_count.toString()))
}
}
if (status.retweet_count > 0) {
countsTexts.add(context.resources.getQuantityString(R.plurals.N_retweets_abbrev,
status.retweet_count.toInt(), status.retweet_count.toLocalizedString()))
status.retweet_count.toInt(), status.retweet_count.toString()))
}
countsLabel.text = countsTexts.joinToString(separator = context.getString(R.string.label_item_separator_comma_localized))
countsLabel.hideIfEmpty()