Merge branch 'maintenance' into origin/master

This commit is contained in:
Tlaster 2020-06-09 15:51:49 +08:00
commit aba0d0be0e
635 changed files with 4438 additions and 2695 deletions

View File

@ -30,14 +30,14 @@ addons:
- git
- ruby
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.m2/
# before_cache:
# - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
# - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
# cache:
# directories:
# - $HOME/.gradle/caches/
# - $HOME/.gradle/wrapper/
# - $HOME/.m2/
before_install:
- ./travis/scripts/decode_private_configs.sh

View File

@ -5,7 +5,7 @@
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/twidere/localized.svg)](https://crowdin.com/project/twidere)
[<img a src="https://c5.patreon.com/external/logo/become_a_patron_button.png" width="100" herf="https://www.patreon.com/bePatron?u=36020799"/>](https://www.patreon.com/bePatron?u=36020799)
Material Design ready and feature rich Twitter/Mastodon/StatusNet/Fanfou app for Android 4.4+. Enjoy Fediverse now!
Material Design ready and feature rich Twitter/Mastodon/StatusNet/Fanfou app for Android 4.1+. Enjoy Fediverse now!
Twidere-Android is maintained by community and supporter including [Dimension](https://dimension.im/).

View File

@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.android.tools.build:gradle:4.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@ -17,13 +17,13 @@ buildscript {
allprojects {
ext {
projectGroupId = 'org.mariotaku.twidere'
projectVersionCode = 512
projectVersionName = '4.1.3'
projectVersionCode = 513
projectVersionName = '4.1.4'
globalCompileSdkVersion = 29
globalBuildToolsVersion = "29.0.3"
globalMinSdkVersion = 19
globalMinSdkVersion = 16
globalTargetSdkVersion = 29
}
@ -39,54 +39,18 @@ subprojects {
buildscript {
ext {
kotlinVersion = '1.3.72'
pluginVersions = [
AndroidSvgDrawable: '3.0.0',
PlayServices : '4.3.3',
]
libVersions = [
sharedVersions = [
Kotlin : "${kotlinVersion}",
SupportTest : '1.0.0',
MariotakuCommons : '0.9.20',
RestFu : '0.9.60',
ObjectCursor : '0.9.21',
PlayServices : '17.0.0',
MapsUtils : '0.6.2',
DropboxCoreSdk : '3.1.3',
GoogleDriveApi : 'v3-rev193-1.25.0',
Exoplayer : '2.11.4',
Toro : '2.1.0',
LoganSquare : '1.3.7',
IABv3 : '1.1.0',
Mime4J : '0.7.2',
OkHttp : '3.8.1',
Stetho : '1.5.0',
OSMDroid : '5.6.5',
LeakCanary : '2.1',
TwitterText : '1.14.7',
MediaViewerLibrary : '0.9.23',
MultiValueSwitch : '0.9.8',
PickNCrop : '0.9.27',
AndroidGIFDrawable : '1.2.6',
KPreferences : '0.9.7',
Kovenant : '3.3.0',
Jackson : '2.7.4',
ParcelablePlease : '1.0.2',
Chameleon : '0.9.28',
UniqR : '0.9.4',
SQLiteQB : '0.9.15',
Glide : '4.11.0',
GlideOkHttp3 : '4.11.0',
GlideTransformations : '4.1.0',
AndroidImageCropper : '2.4.6',
ExportablePreferences: '0.9.7',
ACRA : '4.9.2',
AbstractTask : '0.9.5',
Dagger : '2.11',
StethoBeanShellREPL : '0.1',
MessageBubbleView : '3.5',
MariotakuCommons : '0.9.20',
ObjectCursor : '0.9.21',
RestFu : '0.9.60',
]
}
}
}

View File

@ -1,5 +1,6 @@
org.gradle.jvmargs=-Xmx3584m
#https://github.com/TwidereProject/Twidere-Android/issues/963
android.enableAapt2=false
# android.enableAapt2=false
android.useAndroidX=true
android.enableJetifier=true
android.enableJetifier=true
android.jetifier.blacklist=android-4.1.1.4.jar

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
gradlew vendored
View File

@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath

1
gradlew.bat vendored
View File

@ -84,6 +84,7 @@ set CMD_LINE_ARGS=%*
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

View File

@ -16,8 +16,6 @@
# limitations under the License.
#
org.gradle.jvmargs=-Xmx3584m
org.gradle.parallel=false
kotlin.incremental=false
kotlin.compiler.execution.strategy=in-process
android.useAndroidX=true
android.enableJetifier=true
android.enableJetifier=true
android.jetifier.blacklist=android-4.1.1.4.jar

View File

@ -38,8 +38,8 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
}
}
@ -58,12 +58,19 @@ android {
versionCode projectVersionCode
versionName projectVersionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
@ -72,23 +79,23 @@ dependencies {
/** Third-party dependencies **/
implementation "com.bluelinelabs:logansquare:${libVersions['LoganSquare']}"
annotationProcessor "com.bluelinelabs:logansquare-compiler:${libVersions['LoganSquare']}"
implementation "com.fasterxml.jackson.core:jackson-core:2.7.4"
implementation "com.hannesdorfmann.parcelableplease:annotation:${libVersions['ParcelablePlease']}"
annotationProcessor "com.hannesdorfmann.parcelableplease:processor:${libVersions['ParcelablePlease']}"
implementation "com.bluelinelabs:logansquare:${sharedVersions['LoganSquare']}"
annotationProcessor "com.bluelinelabs:logansquare-compiler:${sharedVersions['LoganSquare']}"
implementation "com.fasterxml.jackson.core:jackson-core:${sharedVersions['Jackson']}"
implementation "com.hannesdorfmann.parcelableplease:annotation:${sharedVersions['ParcelablePlease']}"
annotationProcessor "com.hannesdorfmann.parcelableplease:processor:${sharedVersions['ParcelablePlease']}"
/** Custom dependencies **/
implementation "com.github.mariotaku.RestFu:library:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth2:${libVersions['RestFu']}"
implementation "com.github.mariotaku.ObjectCursor:core:${libVersions['ObjectCursor']}"
annotationProcessor "com.github.mariotaku.ObjectCursor:processor:${libVersions['ObjectCursor']}"
implementation "com.github.mariotaku.ExportablePreferences:core:${libVersions['ExportablePreferences']}"
annotationProcessor "com.github.mariotaku.ExportablePreferences:processor:${libVersions['ExportablePreferences']}"
implementation "com.github.mariotaku.CommonsLibrary:objectcursor:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:logansquare:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.ExportablePreferences:core:${sharedVersions['ExportablePreferences']}"
annotationProcessor "com.github.mariotaku.ExportablePreferences:processor:${sharedVersions['ExportablePreferences']}"
implementation "com.github.mariotaku.CommonsLibrary:logansquare:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:objectcursor:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.ObjectCursor:core:${sharedVersions['ObjectCursor']}"
annotationProcessor "com.github.mariotaku.ObjectCursor:processor:${sharedVersions['ObjectCursor']}"
implementation "com.github.mariotaku.RestFu:library:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth2:${sharedVersions['RestFu']}"
}
install {

View File

@ -206,7 +206,7 @@ public class MicroBlogException extends Exception implements TwitterResponse, Ht
try {
final String retryAfterStr = httpResponse.getHeader("Retry-After");
if (retryAfterStr != null) {
retryAfter = Integer.valueOf(retryAfterStr);
retryAfter = Integer.parseInt(retryAfterStr);
}
} catch (final NumberFormatException ignore) {
}

View File

@ -18,8 +18,11 @@
package org.mariotaku.microblog.library.mastodon.model;
import androidx.annotation.Nullable;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
/**
* {@see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#attachment}
@ -59,6 +62,9 @@ public class Attachment {
@JsonField(name = "text_url")
String textUrl;
@JsonField(name = "meta")
MetaInfo meta;
public String getId() {
return id;
}
@ -83,6 +89,51 @@ public class Attachment {
return textUrl;
}
public MetaInfo getMeta() {
return meta;
}
@JsonObject
public static class MetaInfo {
@ParcelableThisPlease
@JsonField(name = "focus")
@Nullable
public FocusInfo focus;
@ParcelableThisPlease
@JsonField(name = "original")
@Nullable
public MetaDataInfo original;
@ParcelableThisPlease
@JsonField(name = "small")
@Nullable
public MetaDataInfo small;
@JsonObject
public static class FocusInfo {
@ParcelableThisPlease
@JsonField(name = "x")
public float x;
@ParcelableThisPlease
@JsonField(name = "y")
public float y;
}
@JsonObject
public static class MetaDataInfo {
@ParcelableThisPlease
@JsonField(name = "width")
public long width;
@ParcelableThisPlease
@JsonField(name = "height")
public long height;
@ParcelableThisPlease
@JsonField(name = "aspect")
public float aspect;
}
}
@Override
public String toString() {
return "Attachment{" +

View File

@ -64,7 +64,7 @@ public class CardDataMap implements ValueMap {
@Override
public String[] keys() {
final Set<String> keySet = map.keySet();
return keySet.toArray(new String[keySet.size()]);
return keySet.toArray(new String[0]);
}
@Override

View File

@ -37,7 +37,6 @@ import java.util.List;
@Keep
public class IDs$$JsonObjectMapper extends JsonMapper<IDs> {
@SuppressWarnings("TryWithIdenticalCatches")
@Override
public IDs parse(JsonParser jsonParser) throws IOException {
IDs instance = new IDs();

View File

@ -61,11 +61,8 @@ public final class ResponseList$$JsonObjectMapper<T> extends JsonMapper<Response
@Override
public void parseField(ResponseList<T> instance, String fieldName, JsonParser jsonParser) throws IOException {
switch (fieldName) {
case "results": {
instance.addAll(m84ClassJsonMapper.parseList(jsonParser));
break;
}
if ("results".equals(fieldName)) {
instance.addAll(m84ClassJsonMapper.parseList(jsonParser));
}
}

View File

@ -250,7 +250,7 @@ public class UniversalSearchResult {
index.end = jsonParser.nextIntValue(-1);
list.add(index);
}
return list.toArray(new Index[list.size()]);
return list.toArray(new Index[0]);
}
@Override

View File

@ -52,12 +52,9 @@ public final class InternalParseUtil {
accessLevel = TwitterResponse.AccessLevel.READ_WRITE;
break;
case 25:
// read-write-directmessages (Read, Write, & Direct
// Message)
accessLevel = TwitterResponse.AccessLevel.READ_WRITE_DIRECTMESSAGES;
break;
case 26:
// read-write-privatemessages (Read, Write, & Direct
// read-write-directmessages (Read, Write, & Direct
// Message)
accessLevel = TwitterResponse.AccessLevel.READ_WRITE_DIRECTMESSAGES;
break;

View File

@ -64,8 +64,8 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
String ETAG_MASTODON_APPS_PREFERENCES_NAME = "mastodon_apps";
String ACCOUNT_PREFERENCES_NAME_PREFIX = "account_preferences_";
String TWITTER_CONSUMER_KEY = "wmtrtTaVOjUnH5pWQp4LDI5Qs";
String TWITTER_CONSUMER_SECRET = "E9Q9u2yK0COJae2tLcNEdY75OPA3bxqJiGZQztraHaQUtoI2cu";
String TWITTER_CONSUMER_KEY = "MUUBibXUognm6e9vbzrUIqPkt";
String TWITTER_CONSUMER_SECRET = "l2uWAgQkoHvDfM2PrRFx2WN4h7QIUIktmxyeTAqRo6TkGCtNKy";
String YANDEX_KEY = "trnsl.1.1.20200513T065609Z.8e72845b632aa04f.fe1297e42c152de9e8773e1bc71162b1e498e2a8";

View File

@ -56,6 +56,5 @@ public @interface FilterScope {
// Contains all flags
int ALL = 0xFFFFFFFF;
@SuppressWarnings("PointlessBitwiseExpression")
int DEFAULT = ALL & ~(TARGET_NAME | TARGET_DESCRIPTION);
}

View File

@ -291,6 +291,8 @@ public interface SharedPreferenceConstants {
String KEY_AUTO_HIDE_TABS = "auto_hide_tabs";
@ExportablePreference(BOOLEAN)
String KEY_HIDE_CARD_NUMBERS = "hide_card_numbers";
@ExportablePreference(BOOLEAN)
String KEY_SHOW_LINK_PREVIEW = "show_link_preview";
// Internal preferences

View File

@ -40,7 +40,6 @@ import java.util.Arrays;
@JsonObject
@ParcelablePlease
public class ParcelableMedia implements Parcelable {
@SuppressWarnings("NullableProblems")
@NonNull
@JsonField(name = "url")
@ParcelableThisPlease

View File

@ -31,7 +31,6 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
@ParcelablePlease
public class ParcelableMediaUpdate implements Parcelable {
@SuppressWarnings("NullableProblems")
@NonNull
@JsonField(name = "uri")
public String uri;

View File

@ -20,11 +20,11 @@ package org.mariotaku.twidere.model;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.IntDef;
import android.text.TextUtils;
import androidx.annotation.LongDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
@ -52,13 +52,7 @@ import java.util.Comparator;
@ParcelablePlease
public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus>, Cloneable {
public static final Comparator<ParcelableStatus> REVERSE_COMPARATOR = new Comparator<ParcelableStatus>() {
@Override
public int compare(final ParcelableStatus object1, final ParcelableStatus object2) {
return object2.compareTo(object1);
}
};
public static final Comparator<ParcelableStatus> REVERSE_COMPARATOR = (object1, object2) -> object2.compareTo(object1);
public static final Creator<ParcelableStatus> CREATOR = new Creator<ParcelableStatus>() {
@Override
public ParcelableStatus createFromParcel(Parcel source) {
@ -75,13 +69,11 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@CursorField(value = Statuses._ID, excludeWrite = true, type = TwidereDataStore.TYPE_PRIMARY_KEY)
public long _id;
@SuppressWarnings("NullableProblems")
@JsonField(name = "id")
@CursorField(Statuses.ID)
@NonNull
public String id;
@SuppressWarnings("NullableProblems")
@JsonField(name = "account_id", typeConverter = UserKeyConverter.class)
@CursorField(value = Statuses.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)
@NonNull
@ -98,7 +90,6 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "timestamp")
@CursorField(Statuses.TIMESTAMP)
public long timestamp;
@SuppressWarnings("NullableProblems")
@JsonField(name = "user_id", typeConverter = UserKeyConverter.class)
@CursorField(value = Statuses.USER_KEY, converter = UserKeyCursorFieldConverter.class)
@ -527,6 +518,9 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "external_url")
public String external_url;
@JsonField(name = "entities_url")
public String[] entities_url;
@JsonField(name = "quoted_external_url")
public String quoted_external_url;

View File

@ -41,7 +41,6 @@ import java.util.Arrays;
@JsonObject
public class ParcelableStatusUpdate implements Parcelable {
@SuppressWarnings("NullableProblems")
@JsonField(name = "accounts")
@NonNull
@ParcelableThisPlease

View File

@ -45,7 +45,6 @@ public class ParcelableTrend implements Parcelable {
@CursorField(value = CachedTrends._ID, excludeWrite = true, type = TwidereDataStore.TYPE_PRIMARY_KEY)
long _id;
@SuppressWarnings("NullableProblems")
@ParcelableThisPlease
@JsonField(name = "account_id", typeConverter = UserKeyConverter.class)
@CursorField(value = CachedTrends.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)

View File

@ -35,10 +35,8 @@ import java.io.IOException;
public abstract class ConversationExtras implements Parcelable {
public static ConversationExtras parse(@NonNull final String extrasType, @Nullable final String json) throws IOException {
if (json == null) return null;
switch (extrasType) {
case ExtrasType.TWITTER_OFFICIAL: {
return LoganSquare.parse(json, TwitterOfficialConversationExtras.class);
}
if (ExtrasType.TWITTER_OFFICIAL.equals(extrasType)) {
return LoganSquare.parse(json, TwitterOfficialConversationExtras.class);
}
return LoganSquare.parse(json, DefaultConversationExtras.class);
}

View File

@ -46,7 +46,7 @@ public class UserKeysConverter implements TypeConverter<UserKey[]> {
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
list.add(UserKey.valueOf(jsonParser.getValueAsString()));
}
return list.toArray(new UserKey[list.size()]);
return list.toArray(new UserKey[0]);
}
@Override

View File

@ -29,6 +29,12 @@ android {
minSdkVersion globalMinSdkVersion
targetSdkVersion globalTargetSdkVersion
}
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {

View File

@ -314,7 +314,7 @@ public class NyanDrawingHelper {
public void dispatchOnDraw(final Canvas canvas) {
final int w = canvas.getWidth(), h = canvas.getHeight();
if (w <= 0 || h <= 0) return;
for (final Star star : mStars.toArray(new Star[mStars.size()])) {
for (final Star star : mStars.toArray(new Star[0])) {
final int col = star.nextColumn(), row = star.nextRow();
final float y = (row + 0.5f) * (h / mStarRows), x = (col + 0.5f) * (w / mStarCols);
drawStar(canvas, x, y, star.nextFrame());

View File

@ -25,7 +25,7 @@ buildscript {
if (enableGoogleVariant) {
// START Non-FOSS component
classpath "com.google.gms:google-services:${pluginVersions['PlayServices']}"
classpath 'com.google.gms:google-services:4.3.3'
// END Non-FOSS component
}
}
@ -91,9 +91,6 @@ android {
signingConfig signingConfigs.twidere
}
multiDexEnabled true
minifyEnabled false
shrinkResources false
resValue("bool", "debug", "true")
}
release {
@ -101,7 +98,6 @@ android {
signingConfig signingConfigs.twidere
}
multiDexEnabled true
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
@ -115,6 +111,7 @@ android {
}
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -145,7 +142,6 @@ android {
exclude 'sdk-version.txt'
exclude 'build-data.properties'
}
}
task buildTranslationArray {
@ -153,16 +149,16 @@ task buildTranslationArray {
foundLocales.append("new String[]{")
fileTree("src/main/res-localized").visit { FileVisitDetails details ->
if(details.file.path.endsWith("strings.xml")){
def languageCode = details.file.parentFile.name.replaceAll('values-','').replaceAll('-r','-')
languageCode = (languageCode == "values") ? "en" : languageCode;
if (details.file.path.endsWith("strings.xml")) {
def languageCode = details.file.parentFile.name.replaceAll('values-', '').replaceAll('-r', '-')
languageCode = (languageCode == "values") ? "en" : languageCode
foundLocales.append("\"").append(languageCode).append("\"").append(",")
}
}
foundLocales.append("}")
//Don't forget to remove the trailing comma
def foundLocalesString = foundLocales.toString().replaceAll(',}','}')
def foundLocalesString = foundLocales.toString().replaceAll(',}', '}')
android.defaultConfig.buildConfigField "String[]", "TRANSLATION_ARRAY", foundLocalesString
}
@ -175,12 +171,25 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
}
}
ext {
libVersions = [
Kovenant : '3.3.0',
Mime4J : '0.7.2',
Dagger : '2.28',
Exoplayer : '2.11.5',
Glide : '4.11.0',
MediaViewerLibrary: '0.9.23',
PlayServices : '17.0.0',
Stetho : '1.5.1',
]
}
dependencies {
implementation project(':twidere.component.common')
implementation project(':twidere.component.nyan')
/** Kotlin **/
implementation "org.jetbrains.kotlin:kotlin-stdlib:${libVersions['Kotlin']}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${sharedVersions['Kotlin']}"
implementation "nl.komponents.kovenant:kovenant:${libVersions['Kovenant']}"
implementation "nl.komponents.kovenant:kovenant-android:${libVersions['Kovenant']}"
implementation "nl.komponents.kovenant:kovenant-combine:${libVersions['Kovenant']}"
@ -189,103 +198,104 @@ dependencies {
/** Android support **/
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.appcompat:appcompat:1.3.0-alpha01'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.core:core:1.2.0'
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.drawerlayout:drawerlayout:1.1.0-alpha01'
implementation 'androidx.exifinterface:exifinterface:1.1.0'
implementation "androidx.preference:preference:1.1.1"
implementation 'androidx.exifinterface:exifinterface:1.2.0'
implementation 'androidx.legacy:legacy-support-core-ui:1.0.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation "androidx.core:core-ktx:1.2.0"
/** Third-party dependencies **/
compileOnly 'javax.annotation:jsr250-api:1.0'
implementation "com.twitter:twitter-text:${libVersions['TwitterText']}"
implementation 'com.twitter:twitter-text:1.14.7'
implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
implementation 'com.squareup:otto:1.3.8'
implementation 'dnsjava:dnsjava:2.1.8'
implementation 'com.commonsware.cwac:layouts:0.4.3'
implementation 'dnsjava:dnsjava:2.1.9'
implementation 'com.commonsware.cwac:layouts:0.4.5'
implementation 'com.rengwuxian.materialedittext:library:2.1.4'
implementation 'com.pnikosis:materialish-progress:1.7'
implementation 'com.github.uucky:ColorPicker-Android:0.9.7@aar'
implementation "pl.droidsonroids.gif:android-gif-drawable:${libVersions['AndroidGIFDrawable']}"
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
implementation 'com.sprylab.android.texturevideoview:texturevideoview:1.2.1'
implementation 'com.squareup:pollexor:2.0.4'
implementation 'org.apache.commons:commons-text:1.8'
implementation "org.apache.james:apache-mime4j-core:${libVersions['Mime4J']}"
implementation "org.apache.james:apache-mime4j-storage:${libVersions['Mime4J']}"
implementation "com.bluelinelabs:logansquare:${libVersions['LoganSquare']}"
kapt "com.bluelinelabs:logansquare-compiler:${libVersions['LoganSquare']}"
implementation "com.fasterxml.jackson.core:jackson-core:2.7.4"
implementation "com.hannesdorfmann.parcelableplease:annotation:${libVersions['ParcelablePlease']}"
kapt "com.hannesdorfmann.parcelableplease:processor:${libVersions['ParcelablePlease']}"
implementation "com.squareup.okhttp3:okhttp:${libVersions['OkHttp']}"
implementation "com.squareup.okio:okio:2.4.3"
implementation "com.bluelinelabs:logansquare:${sharedVersions['LoganSquare']}"
kapt "com.bluelinelabs:logansquare-compiler:${sharedVersions['LoganSquare']}"
implementation "com.fasterxml.jackson.core:jackson-core:${sharedVersions['Jackson']}"
implementation "com.hannesdorfmann.parcelableplease:annotation:${sharedVersions['ParcelablePlease']}"
kapt "com.hannesdorfmann.parcelableplease:processor:${sharedVersions['ParcelablePlease']}"
implementation 'com.squareup.okhttp3:okhttp:3.12.12'
implementation 'com.squareup.okio:okio:2.6.0'
implementation 'com.lnikkila:extendedtouchview:0.1.1'
implementation "com.google.dagger:dagger:${libVersions['Dagger']}"
kapt "com.google.dagger:dagger-compiler:${libVersions['Dagger']}"
implementation 'org.attoparser:attoparser:2.0.4.RELEASE'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.9.1'
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
implementation 'org.attoparser:attoparser:2.0.5.RELEASE'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.3.0'
implementation 'org.jsoup:jsoup:1.13.1'
implementation "com.google.android.exoplayer:exoplayer-core:${libVersions['Exoplayer']}"
implementation "com.google.android.exoplayer:exoplayer-ui:${libVersions['Exoplayer']}"
implementation "com.google.android.exoplayer:extension-okhttp:${libVersions['Exoplayer']}"
implementation "com.github.bumptech.glide:glide:${libVersions['Glide']}"
implementation "com.github.bumptech.glide:okhttp3-integration:${libVersions['GlideOkHttp3']}@aar"
implementation "com.github.bumptech.glide:okhttp3-integration:${libVersions['Glide']}@aar"
kapt "com.github.bumptech.glide:compiler:${libVersions['Glide']}"
implementation "jp.wasabeef:glide-transformations:${libVersions['GlideTransformations']}"
implementation "com.theartofdev.edmodo:android-image-cropper:${libVersions['AndroidImageCropper']}"
implementation 'jp.wasabeef:glide-transformations:4.1.0'
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
/** Custom dependencies **/
implementation 'com.github.mariotaku:AbstractTask:0.9.5'
implementation 'com.github.mariotaku:DragSortListView:0.6.1'
implementation "com.github.mariotaku:MessageBubbleView:${libVersions['MessageBubbleView']}"
implementation 'com.github.mariotaku:DragSortListView:0.6.1'
implementation "com.github.mariotaku.MediaViewerLibrary:base:${libVersions['MediaViewerLibrary']}"
implementation "com.github.mariotaku.MediaViewerLibrary:subsample-image-view:${libVersions['MediaViewerLibrary']}"
implementation "com.github.mariotaku:SQLiteQB:${libVersions['SQLiteQB']}"
implementation "com.github.mariotaku.ObjectCursor:core:${libVersions['ObjectCursor']}"
kapt "com.github.mariotaku.ObjectCursor:processor:${libVersions['ObjectCursor']}"
implementation "com.github.mariotaku.ExportablePreferences:core:${libVersions['ExportablePreferences']}"
implementation "com.github.mariotaku:AbstractTask:${libVersions['AbstractTask']}"
implementation "com.github.mariotaku.CommonsLibrary:parcel:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:io:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:text:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:text-kotlin:${libVersions['MariotakuCommons']}"
implementation("com.github.mariotaku.CommonsLibrary:emojione-android:${libVersions['MariotakuCommons']}") {
implementation "com.github.mariotaku.ExportablePreferences:core:${sharedVersions['ExportablePreferences']}"
implementation("com.github.mariotaku.CommonsLibrary:emojione-android:${sharedVersions['MariotakuCommons']}") {
exclude group: 'org.apache.commons', module: 'commons-text'
}
implementation "com.github.mariotaku.CommonsLibrary:objectcursor:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:logansquare:${libVersions['MariotakuCommons']}"
implementation "com.github.mariotaku:KPreferences:${libVersions['KPreferences']}"
implementation "com.github.mariotaku.UniqR:android:${libVersions['UniqR']}"
implementation "com.github.mariotaku:PickNCrop:${libVersions['PickNCrop']}"
implementation "com.github.mariotaku.RestFu:library:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth2:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:okhttp3:${libVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:logansquare:${libVersions['RestFu']}"
implementation "com.github.Tlaster:Chameleon:${libVersions['Chameleon']}"
implementation "com.github.mariotaku.CommonsLibrary:io:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:logansquare:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:objectcursor:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:parcel:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:text:${sharedVersions['MariotakuCommons']}"
implementation "com.github.mariotaku.CommonsLibrary:text-kotlin:${sharedVersions['MariotakuCommons']}"
implementation 'com.github.mariotaku:KPreferences:0.9.8'
implementation "com.github.mariotaku.MediaViewerLibrary:base:${libVersions['MediaViewerLibrary']}"
implementation "com.github.mariotaku.MediaViewerLibrary:subsample-image-view:${libVersions['MediaViewerLibrary']}"
implementation 'com.github.mariotaku:MessageBubbleView:3.5'
implementation "com.github.mariotaku.ObjectCursor:core:${sharedVersions['ObjectCursor']}"
kapt "com.github.mariotaku.ObjectCursor:processor:${sharedVersions['ObjectCursor']}"
implementation 'com.github.mariotaku:PickNCrop:0.9.27'
implementation "com.github.mariotaku.RestFu:library:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:logansquare:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:oauth2:${sharedVersions['RestFu']}"
implementation "com.github.mariotaku.RestFu:okhttp3:${sharedVersions['RestFu']}"
implementation 'com.github.mariotaku:SQLiteQB:0.9.15'
implementation 'com.github.mariotaku.UniqR:android:0.9.4'
implementation 'com.github.Tlaster:Chameleon:0.9.28'
/** Flavor dependencies **/
fdroidImplementation "org.osmdroid:osmdroid-android:${libVersions['OSMDroid']}"
fdroidImplementation "ch.acra:acra:${libVersions['ACRA']}"
fdroidImplementation 'org.osmdroid:osmdroid-android:5.6.5'
fdroidImplementation 'ch.acra:acra:4.11'
if (enableGoogleVariant) {
// START Non-FOSS component
googleImplementation "com.google.android.gms:play-services-ads:${libVersions['PlayServices']}"
googleImplementation "com.google.android.gms:play-services-auth:${libVersions['PlayServices']}"
googleImplementation "com.google.android.gms:play-services-maps:${libVersions['PlayServices']}"
googleImplementation "com.google.maps.android:android-maps-utils:${libVersions['MapsUtils']}"
googleImplementation "com.anjlab.android.iab.v3:library:${libVersions['IABv3']}"
googleImplementation "com.dropbox.core:dropbox-core-sdk:${libVersions['DropboxCoreSdk']}"
googleImplementation("com.google.apis:google-api-services-drive:${libVersions['GoogleDriveApi']}") {
googleImplementation 'com.google.maps.android:android-maps-utils:0.6.2'
googleImplementation 'com.anjlab.android.iab.v3:library:1.1.0'
googleImplementation 'com.dropbox.core:dropbox-core-sdk:3.1.3'
googleImplementation('com.google.apis:google-api-services-drive:v3-rev195-1.25.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.guava:guava:28.2-android'
@ -294,9 +304,9 @@ dependencies {
debugImplementation "com.facebook.stetho:stetho:${libVersions['Stetho']}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${libVersions['Stetho']}"
debugImplementation "com.github.mariotaku:StethoBeanShellREPL:${libVersions['StethoBeanShellREPL']}"
debugImplementation "com.squareup.leakcanary:leakcanary-android:${libVersions['LeakCanary']}"
debugImplementation('com.jayway.jsonpath:json-path:2.2.0') {
debugImplementation 'com.github.mariotaku:StethoBeanShellREPL:0.5'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
debugImplementation('com.jayway.jsonpath:json-path:2.4.0') {
exclude group: 'net.minidev', module: 'json-smart'
}
// Stetho dependency, see https://g.co/androidstudio/app-test-app-conflict

View File

@ -316,9 +316,9 @@ class AccountsDumperPlugin(val context: Context) : DumperPlugin {
return JsonPath.parse(JsonSerializer.serialize(details), configuration)
}
private fun Any.prettyPrint() = when {
this is JSONObject -> toString(4)
this is JSONArray -> toString(4)
private fun Any.prettyPrint() = when (this) {
is JSONObject -> toString(4)
is JSONArray -> toString(4)
else -> toString()
}

View File

@ -7,8 +7,8 @@
"auth_type": "oauth",
"same_oauth_url": true,
"no_version_suffix": false,
"consumer_key": "wmtrtTaVOjUnH5pWQp4LDI5Qs",
"consumer_secret": "E9Q9u2yK0COJae2tLcNEdY75OPA3bxqJiGZQztraHaQUtoI2cu",
"consumer_key": "MUUBibXUognm6e9vbzrUIqPkt",
"consumer_secret": "l2uWAgQkoHvDfM2PrRFx2WN4h7QIUIktmxyeTAqRo6TkGCtNKy",
"sign_up_url": "https://twitter.com/signup"
},
{

View File

@ -1,68 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.commons.text.translate;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
/**
* Executes a sequence of translators one after the other. Execution ends whenever
* the first translator consumes codepoints from the input.
*
* @since 1.0
*/
public class AggregateTranslator extends CharSequenceTranslator {
/**
* Translator list.
*/
private final List<CharSequenceTranslator> translators = new ArrayList<>();
/**
* Specify the translators to be used at creation time.
*
* @param translators CharSequenceTranslator array to aggregate
*/
public AggregateTranslator(final CharSequenceTranslator... translators) {
if (translators != null) {
for (CharSequenceTranslator translator : translators) {
if (translator != null) {
this.translators.add(translator);
}
}
}
}
/**
* The first translator to consume codepoints from the input is the 'winner'.
* Execution stops with the number of consumed codepoints being returned.
* {@inheritDoc}
*/
@Override
public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
for (final CharSequenceTranslator translator : translators) {
final int consumed = translator.translate(input, index, out);
if (consumed != 0) {
return consumed;
}
}
return 0;
}
}

View File

@ -1,140 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.commons.text.translate;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Locale;
/**
* An API for translating text.
* Its core use is to escape and unescape text. Because escaping and unescaping
* is completely contextual, the API does not present two separate signatures.
*
* @since 1.0
*/
public abstract class CharSequenceTranslator {
/**
* Array containing the hexadecimal alphabet.
*/
static final char[] HEX_DIGITS = new char[]{'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'};
/**
* Translate a set of codepoints, represented by an int index into a CharSequence,
* into another set of codepoints. The number of codepoints consumed must be returned,
* and the only IOExceptions thrown must be from interacting with the Writer so that
* the top level API may reliably ignore StringWriter IOExceptions.
*
* @param input CharSequence that is being translated
* @param index int representing the current point of translation
* @param out Writer to translate the text to
* @return int count of codepoints consumed
* @throws IOException if and only if the Writer produces an IOException
*/
public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
/**
* Helper for non-Writer usage.
*
* @param input CharSequence to be translated
* @return String output of translation
*/
public final String translate(final CharSequence input) {
if (input == null) {
return null;
}
try {
final StringWriter writer = new StringWriter(input.length() * 2);
translate(input, writer);
return writer.toString();
} catch (final IOException ioe) {
// this should never ever happen while writing to a StringWriter
throw new RuntimeException(ioe);
}
}
/**
* Translate an input onto a Writer. This is intentionally final as its algorithm is
* tightly coupled with the abstract method of this class.
*
* @param input CharSequence that is being translated
* @param out Writer to translate the text to
* @throws IOException if and only if the Writer produces an IOException
*/
public final void translate(final CharSequence input, final Writer out) throws IOException {
if (out == null) throw new IllegalArgumentException("The Writer must not be null");
if (input == null) {
return;
}
int pos = 0;
final int len = input.length();
while (pos < len) {
final int consumed = translate(input, pos, out);
if (consumed == 0) {
// inlined implementation of Character.toChars(Character.codePointAt(input, pos))
// avoids allocating temp char arrays and duplicate checks
final char c1 = input.charAt(pos);
out.write(c1);
pos++;
if (Character.isHighSurrogate(c1) && pos < len) {
final char c2 = input.charAt(pos);
if (Character.isLowSurrogate(c2)) {
out.write(c2);
pos++;
}
}
continue;
}
// contract with translators is that they have to understand codepoints
// and they just took care of a surrogate pair
for (int pt = 0; pt < consumed; pt++) {
pos += Character.charCount(Character.codePointAt(input, pos));
}
}
}
/**
* Helper method to create a merger of this translator with another set of
* translators. Useful in customizing the standard functionality.
*
* @param translators CharSequenceTranslator array of translators to merge with this one
* @return CharSequenceTranslator merging this translator with the others
*/
public final CharSequenceTranslator with(final CharSequenceTranslator... translators) {
final CharSequenceTranslator[] newArray = new CharSequenceTranslator[translators.length + 1];
newArray[0] = this;
System.arraycopy(translators, 0, newArray, 1, translators.length);
return new AggregateTranslator(newArray);
}
/**
* <p>Returns an upper case hexadecimal <code>String</code> for the given
* character.</p>
*
* @param codepoint The codepoint to convert.
* @return An upper case hexadecimal <code>String</code>
*/
public static String hex(final int codepoint) {
return Integer.toHexString(codepoint).toUpperCase(Locale.ENGLISH);
}
}

View File

@ -1,51 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.commons.text.translate;
import java.io.IOException;
import java.io.Writer;
/**
* Helper subclass to CharSequenceTranslator to allow for translations that
* will replace up to one character at a time.
*
* @since 1.0
*/
public abstract class CodePointTranslator extends CharSequenceTranslator {
/**
* Implementation of translate that maps onto the abstract translate(int, Writer) method.
* {@inheritDoc}
*/
@Override
public final int translate(final CharSequence input, final int index, final Writer out) throws IOException {
final int codepoint = Character.codePointAt(input, index);
final boolean consumed = translate(codepoint, out);
return consumed ? 1 : 0;
}
/**
* Translate the specified codepoint into another.
*
* @param codepoint int character input to translate
* @param out Writer to optionally push the translated output to
* @return boolean as to whether translation occurred or not
* @throws IOException if and only if the Writer produces an IOException
*/
public abstract boolean translate(int codepoint, Writer out) throws IOException;
}

View File

@ -1,104 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.commons.text.translate;
import java.io.IOException;
import java.io.Writer;
import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
/**
* Translates a value using a lookup table.
*
* @since 1.0
*/
public class LookupTranslator extends CharSequenceTranslator {
/** The mapping to be used in translation. */
private final Map<String, String> lookupMap;
/** The first character of each key in the lookupMap. */
private final HashSet<Character> prefixSet;
/** The length of the shortest key in the lookupMap. */
private final int shortest;
/** The length of the longest key in the lookupMap. */
private final int longest;
/**
* Define the lookup table to be used in translation
*
* Note that, as of Lang 3.1 (the orgin of this code), the key to the lookup
* table is converted to a java.lang.String. This is because we need the key
* to support hashCode and equals(Object), allowing it to be the key for a
* HashMap. See LANG-882.
*
* @param lookupMap Map&lt;CharSequence, CharSequence&gt; table of translator
* mappings
*/
public LookupTranslator(final Map<CharSequence, CharSequence> lookupMap) {
if (lookupMap == null) {
throw new InvalidParameterException("lookupMap cannot be null");
}
this.lookupMap = new HashMap<>();
this.prefixSet = new HashSet<>();
int currentShortest = Integer.MAX_VALUE;
int currentLongest = 0;
Iterator<Map.Entry<CharSequence, CharSequence>> it = lookupMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<CharSequence, CharSequence> pair = it.next();
this.lookupMap.put(pair.getKey().toString(), pair.getValue().toString());
this.prefixSet.add(pair.getKey().charAt(0));
final int sz = pair.getKey().length();
if (sz < currentShortest) {
currentShortest = sz;
}
if (sz > currentLongest) {
currentLongest = sz;
}
}
this.shortest = currentShortest;
this.longest = currentLongest;
}
/**
* {@inheritDoc}
*/
@Override
public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
// check if translation exists for the input at position index
if (prefixSet.contains(input.charAt(index))) {
int max = longest;
if (index + longest > input.length()) {
max = input.length() - index;
}
// implement greedy algorithm by trying maximum match first
for (int i = max; i >= shortest; i--) {
final CharSequence subSeq = input.subSequence(index, index + i);
final String result = lookupMap.get(subSeq.toString());
if (result != null) {
out.write(result);
return i;
}
}
}
return 0;
}
}

View File

@ -1,139 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.commons.text.translate;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.EnumSet;
/**
* Translate XML numeric entities of the form &amp;#[xX]?\d+;? to
* the specific codepoint.
*
* Note that the semi-colon is optional.
*
* @since 1.0
*/
public class NumericEntityUnescaper extends CharSequenceTranslator {
/** NumericEntityUnescaper option enum. */
public enum OPTION { semiColonRequired, semiColonOptional, errorIfNoSemiColon }
/** EnumSet of OPTIONS, given from the constructor. */
private final EnumSet<OPTION> options;
/**
* Create a UnicodeUnescaper.
*
* The constructor takes a list of options, only one type of which is currently
* available (whether to allow, error or ignore the semi-colon on the end of a
* numeric entity to being missing).
*
* For example, to support numeric entities without a ';':
* new NumericEntityUnescaper(NumericEntityUnescaper.OPTION.semiColonOptional)
* and to throw an IllegalArgumentException when they're missing:
* new NumericEntityUnescaper(NumericEntityUnescaper.OPTION.errorIfNoSemiColon)
*
* Note that the default behaviour is to ignore them.
*
* @param options to apply to this unescaper
*/
public NumericEntityUnescaper(final OPTION... options) {
if (options.length > 0) {
this.options = EnumSet.copyOf(Arrays.asList(options));
} else {
this.options = EnumSet.of(OPTION.semiColonRequired);
}
}
/**
* Whether the passed in option is currently set.
*
* @param option to check state of
* @return whether the option is set
*/
public boolean isSet(final OPTION option) {
return options != null && options.contains(option);
}
/**
* {@inheritDoc}
*/
@Override
public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
final int seqEnd = input.length();
// Uses -2 to ensure there is something after the &#
if (input.charAt(index) == '&' && index < seqEnd - 2 && input.charAt(index + 1) == '#') {
int start = index + 2;
boolean isHex = false;
final char firstChar = input.charAt(start);
if (firstChar == 'x' || firstChar == 'X') {
start++;
isHex = true;
// Check there's more than just an x after the &#
if (start == seqEnd) {
return 0;
}
}
int end = start;
// Note that this supports character codes without a ; on the end
while (end < seqEnd && (input.charAt(end) >= '0' && input.charAt(end) <= '9'
|| input.charAt(end) >= 'a' && input.charAt(end) <= 'f'
|| input.charAt(end) >= 'A' && input.charAt(end) <= 'F')) {
end++;
}
final boolean semiNext = end != seqEnd && input.charAt(end) == ';';
if (!semiNext) {
if (isSet(OPTION.semiColonRequired)) {
return 0;
} else {
if (isSet(OPTION.errorIfNoSemiColon)) {
throw new IllegalArgumentException("Semi-colon required at end of numeric entity");
}
}
}
int entityValue;
try {
if (isHex) {
entityValue = Integer.parseInt(input.subSequence(start, end).toString(), 16);
} else {
entityValue = Integer.parseInt(input.subSequence(start, end).toString(), 10);
}
} catch (final NumberFormatException nfe) {
return 0;
}
if (entityValue > 0xFFFF) {
final char[] chrs = Character.toChars(entityValue);
out.write(chrs[0]);
out.write(chrs[1]);
} else {
out.write(entityValue);
}
return 2 + end - start + (isHex ? 1 : 0) + (semiNext ? 1 : 0);
}
return 0;
}
}

View File

@ -91,6 +91,7 @@ public interface Constants extends TwidereConstants {
String TWIDERE_PREVIEW_NAME = "Twidere Project";
String TWIDERE_PREVIEW_SCREEN_NAME = "TwidereProject";
String TWIDERE_PREVIEW_TEXT_HTML = "Twidere is an open source twitter client for Android, see <a href='https://github.com/mariotaku/twidere'>github.com/mariotak&#8230;</a>";
String TWIDERE_PREVIEW_LINK_URI = "https://github.com/TwidereProject/Twidere-Android";
String TWIDERE_PREVIEW_TEXT_UNESCAPED = "Twidere is an open source twitter client for Android, see github.com/mariotak&#8230;";
String TWIDERE_PREVIEW_SOURCE = "Twidere for Android";

View File

@ -101,7 +101,7 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* instantiating views.
*/
public ArrayAdapter(Context context, int resource) {
init(context, resource, new ArrayList<T>());
init(context, resource, new ArrayList<>());
}
/**

View File

@ -84,12 +84,9 @@ public class ExtendedDividerItemDecoration extends RecyclerView.ItemDecoration {
}
public void setPadding(final int left, final int top, final int right, final int bottom) {
mPadding = new Padding() {
@Override
public boolean get(int position, Rect rect) {
rect.set(left, top, right, bottom);
return true;
}
mPadding = (position, rect) -> {
rect.set(left, top, right, bottom);
return true;
};
}

View File

@ -66,12 +66,9 @@ public final class DataExportImportTypeSelectorDialogFragment extends BaseDialog
@Override
public final void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
final int flags = getCheckedFlags();
onPositiveButtonClicked(flags);
break;
}
if (which == DialogInterface.BUTTON_POSITIVE) {
final int flags = getCheckedFlags();
onPositiveButtonClicked(flags);
}
}

View File

@ -118,14 +118,11 @@ public class FileSelectorDialogFragment extends BaseDialogFragment implements Lo
builder.setPositiveButton(android.R.string.ok, this);
}
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(final DialogInterface dialog) {
final AlertDialog alertDialog = (AlertDialog) dialog;
DialogExtensionsKt.applyTheme(alertDialog);
final ListView listView = alertDialog.getListView();
listView.setOnItemClickListener(FileSelectorDialogFragment.this);
}
dialog.setOnShowListener(dialog1 -> {
final AlertDialog alertDialog = (AlertDialog) dialog1;
DialogExtensionsKt.applyTheme(alertDialog);
final ListView listView = alertDialog.getListView();
listView.setOnItemClickListener(FileSelectorDialogFragment.this);
});
return dialog;
}
@ -268,12 +265,9 @@ public class FileSelectorDialogFragment extends BaseDialogFragment implements Lo
private final String[] extensions;
private final Pattern extensions_regex;
private static final Comparator<File> NAME_COMPARATOR = new Comparator<File>() {
@Override
public int compare(final File file1, final File file2) {
final Locale loc = Locale.getDefault();
return file1.getName().toLowerCase(loc).compareTo(file2.getName().toLowerCase(loc));
}
private static final Comparator<File> NAME_COMPARATOR = (file1, file2) -> {
final Locale loc = Locale.getDefault();
return file1.getName().toLowerCase(loc).compareTo(file2.getName().toLowerCase(loc));
};
public FilesLoader(final Context context, final File path, final String[] extensions) {

View File

@ -24,7 +24,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import androidx.annotation.NonNull;
@ -66,12 +65,10 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.reset: {
final DialogFragment f = new ResetKeyboardShortcutConfirmDialogFragment();
f.show(getFragmentManager(), "reset_keyboard_shortcut_confirm");
return true;
}
if (item.getItemId() == R.id.reset) {
final DialogFragment f = new ResetKeyboardShortcutConfirmDialogFragment();
f.show(getFragmentManager(), "reset_keyboard_shortcut_confirm");
return true;
}
return super.onOptionsItemSelected(item);
}
@ -90,12 +87,7 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
mAction = action;
setPersistent(false);
setTitle(KeyboardShortcutsHandler.getActionLabel(context, action));
mPreferencesChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
updateSummary();
}
};
mPreferencesChangeListener = (preferences, key) -> updateSummary();
updateSummary();
}
@ -103,8 +95,8 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
protected void onClick() {
final Context context = getContext();
final Intent intent = new Intent(context, KeyboardShortcutPreferenceCompatActivity.class);
intent.putExtra(KeyboardShortcutPreferenceCompatActivity.Companion.getEXTRA_CONTEXT_TAG(), mContextTag);
intent.putExtra(KeyboardShortcutPreferenceCompatActivity.Companion.getEXTRA_KEY_ACTION(), mAction);
intent.putExtra(KeyboardShortcutPreferenceCompatActivity.EXTRA_CONTEXT_TAG, mContextTag);
intent.putExtra(KeyboardShortcutPreferenceCompatActivity.EXTRA_KEY_ACTION, mAction);
context.startActivity(intent);
}
@ -132,11 +124,8 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
implements OnClickListener {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
keyboardShortcutsHandler.reset();
break;
}
if (which == DialogInterface.BUTTON_POSITIVE) {
keyboardShortcutsHandler.reset();
}
}
@ -148,12 +137,7 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(final DialogInterface dialog) {
DialogExtensionsKt.applyTheme((AlertDialog) dialog);
}
});
dialog.setOnShowListener(dialog1 -> DialogExtensionsKt.applyTheme((AlertDialog) dialog1));
return dialog;
}
}

View File

@ -47,24 +47,21 @@ public class ThemedListPreferenceDialogFragmentCompat extends ThemedPreferenceDi
}
mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
builder.setSingleChoiceItems(entries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
/*
* Clicking on an item simulates the positive button
* click, and dismisses the dialog.
*/
ThemedListPreferenceDialogFragmentCompat.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
(dialog, which) -> {
mClickedDialogEntryIndex = which;
/*
* Clicking on an item simulates the positive button
* click, and dismisses the dialog.
*/
ThemedListPreferenceDialogFragmentCompat.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
});
/*
* The typical interaction for list-based dialogs is to have
* click-on-an-item dismiss the dialog instead of the user having to
* press 'Ok'.
*/
//noinspection ConstantConditions
builder.setPositiveButton(null, null);
}

View File

@ -68,7 +68,6 @@ public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> {
return new ObjectCursor<>(cursor, indices, mUseCache);
}
@SuppressWarnings("TryWithIdenticalCatches")
@NonNull
private ObjectCursor.CursorIndices<T> createIndices(final Cursor cursor) {
return ObjectCursor.indicesFrom(cursor, mObjectClass);

View File

@ -447,7 +447,7 @@ public class CronExpression {
if (match) {
list.add(str.substring(start, i));
}
return list.toArray(new String[list.size()]);
return list.toArray(new String[0]);
}
}

View File

@ -92,11 +92,7 @@ public abstract class DrawableHolder {
}
public static DrawableHolder parse(String str) {
DrawableHolder icon = builtin(str);
if (icon != null) {
return icon;
}
return null;
return builtin(str);
}
public static List<DrawableHolder> builtins() {

View File

@ -100,12 +100,7 @@ abstract class MultiSelectListPreference extends DialogPreference implements IDi
builder.setNegativeButton(android.R.string.cancel, null);
builder.setMultiChoiceItems(mNames, mValues, this);
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(final DialogInterface dialog) {
DialogExtensionsKt.applyTheme((AlertDialog) dialog);
}
});
dialog.setOnShowListener(dialog1 -> DialogExtensionsKt.applyTheme((AlertDialog) dialog1));
return dialog;
}

View File

@ -21,7 +21,6 @@ package org.mariotaku.twidere.preference;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
@ -78,19 +77,9 @@ public class SettingsImportExportPreference extends DialogPreference implements
entries[1] = context.getString(R.string.export_settings);
values[0] = new Intent(context, DataImportActivity.class);
values[1] = new Intent(context, DataExportActivity.class);
builder.setItems(entries, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(values[which]);
}
});
builder.setItems(entries, (dialog, which) -> startActivity(values[which]));
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(final DialogInterface dialog) {
DialogExtensionsKt.applyTheme((AlertDialog) dialog);
}
});
dialog.setOnShowListener(dialog1 -> DialogExtensionsKt.applyTheme((AlertDialog) dialog1));
return dialog;
}

View File

@ -2,8 +2,6 @@ package org.mariotaku.twidere.preference;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
@ -17,7 +15,6 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SeekBar;
@ -160,42 +157,33 @@ public class ThemeBackgroundPreference extends DialogPreference implements Const
final SharedPreferences preferences = preference.getSharedPreferences();
preference.setValue(preference.getPersistedString(null));
builder.setTitle(preference.getDialogTitle());
builder.setSingleChoiceItems(preference.mBackgroundEntries, preference.getValueIndex(), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preference.setSelectedOption(which);
updateAlphaVisibility();
}
builder.setSingleChoiceItems(preference.mBackgroundEntries, preference.getValueIndex(), (dialog, which) -> {
preference.setSelectedOption(which);
updateAlphaVisibility();
});
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
final Dialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
final AlertDialog alertDialog = (AlertDialog) dialog;
DialogExtensionsKt.applyTheme(alertDialog);
if (preferences != null) {
final LayoutInflater inflater = alertDialog.getLayoutInflater();
final ListView listView = alertDialog.getListView();
assert listView != null;
final ViewGroup listViewParent = (ViewGroup) listView.getParent();
listViewParent.removeView(listView);
final View view = inflater.inflate(R.layout.dialog_theme_background_preference, listViewParent);
((ViewGroup) view.findViewById(R.id.list_container)).addView(listView);
mAlphaContainer = view.findViewById(R.id.alpha_container);
mAlphaSlider = view.findViewById(R.id.alpha_slider);
mAlphaSlider.setMax(MAX_ALPHA - MIN_ALPHA);
mAlphaSlider.setProgress(preferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA) - MIN_ALPHA);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
preference.setSelectedOption(position);
updateAlphaVisibility();
}
});
dialog.setOnShowListener(dialog1 -> {
final AlertDialog alertDialog = (AlertDialog) dialog1;
DialogExtensionsKt.applyTheme(alertDialog);
if (preferences != null) {
final LayoutInflater inflater = alertDialog.getLayoutInflater();
final ListView listView = alertDialog.getListView();
assert listView != null;
final ViewGroup listViewParent = (ViewGroup) listView.getParent();
listViewParent.removeView(listView);
final View view = inflater.inflate(R.layout.dialog_theme_background_preference, listViewParent);
((ViewGroup) view.findViewById(R.id.list_container)).addView(listView);
mAlphaContainer = view.findViewById(R.id.alpha_container);
mAlphaSlider = view.findViewById(R.id.alpha_slider);
mAlphaSlider.setMax(MAX_ALPHA - MIN_ALPHA);
mAlphaSlider.setProgress(preferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA) - MIN_ALPHA);
listView.setOnItemClickListener((parent, view1, position, id) -> {
preference.setSelectedOption(position);
updateAlphaVisibility();
}
});
updateAlphaVisibility();
}
});
return dialog;

View File

@ -31,7 +31,6 @@ import androidx.annotation.Nullable;
import org.mariotaku.twidere.constant.IntentConstants;
import org.mariotaku.twidere.util.ServiceUtils.ServiceToken;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@ -73,12 +72,7 @@ public abstract class AbsServiceInterface<I extends IInterface> implements IInte
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_EXTENSION_SHORTEN_STATUS);
final ComponentName component = ComponentName.unflattenFromString(mShortenerName);
intent.setComponent(component);
final FutureTask<Boolean> futureTask = new FutureTask<>(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return mIInterface != null;
}
});
final FutureTask<Boolean> futureTask = new FutureTask<>(() -> mIInterface != null);
mToken = ServiceUtils.bindToService(mContext, intent, new ServiceConnection() {
@Override
public void onServiceConnected(final ComponentName name, final IBinder obj) {
@ -112,7 +106,6 @@ public abstract class AbsServiceInterface<I extends IInterface> implements IInte
}
public interface CheckServiceAction {
@SuppressWarnings("RedundantThrows")
void check(@Nullable Bundle metaData) throws CheckServiceException;
}

View File

@ -26,6 +26,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
@ -169,7 +170,7 @@ public class DataImportExportUtils implements Constants {
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
int flags = 0;
List<String> entryNames = new ArrayList<>();
ZipEntry entry = null;
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
entryNames.add(entry.getName());
}
@ -203,11 +204,11 @@ public class DataImportExportUtils implements Constants {
try (InputStream inputStream = context.getContentResolver().openInputStream(src.getUri());
ZipInputStream zipInputStream = new ZipInputStream(inputStream)
) {
ZipEntry entry = null;
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
StringBuilder stringBuilder = new StringBuilder();
byte[] buffer = new byte[1024];
int read = 0;
int read;
while ((read = zipInputStream.read(buffer, 0, 1024)) >= 0) {
stringBuilder.append(new String(buffer, 0, read));
}
@ -292,7 +293,15 @@ public class DataImportExportUtils implements Constants {
@NonNull final String preferencesName, @NonNull final String entryName,
@NonNull final SharedPreferencesProcessStrategy strategy,
@NonNull final String data) throws IOException {
if (!Objects.equals(entry.getName(), entryName)) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (!Objects.equals(entry.getName(), entryName)) {
return;
}
} else {
if (entry.getName().equals(entryName)) {
return;
}
}
final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(data);
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
@ -327,7 +336,15 @@ public class DataImportExportUtils implements Constants {
@NonNull final String data,
@NonNull final ContentResolverProcessStrategy<List<T>> strategy)
throws IOException {
if (!Objects.equals(entry.getName(), entryName)) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (!Objects.equals(entry.getName(), entryName)) {
return;
}
} else {
if (entry.getName().equals(entryName)) {
return;
}
}
List<T> itemsList = JsonSerializer.parseList(data, itemCls);
strategy.importItem(context.getContentResolver(), itemsList);
}
@ -352,7 +369,15 @@ public class DataImportExportUtils implements Constants {
@NonNull final String data,
@NonNull final ContentResolverProcessStrategy<T> strategy)
throws IOException {
if (!Objects.equals(entry.getName(), entryName)) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (!Objects.equals(entry.getName(), entryName)) {
return;
}
} else {
if (entry.getName().equals(entryName)) {
return;
}
}
T item = JsonSerializer.parse(data, itemCls);
strategy.importItem(context.getContentResolver(), item);
}

View File

@ -132,7 +132,7 @@ public class MouseScrollDirectionDecider {
}
@SuppressLint("ViewConstructor")
private class InternalHorizontalScrollView extends HorizontalScrollView {
private static class InternalHorizontalScrollView extends HorizontalScrollView {
private final int factor;
private final MouseScrollDirectionDecider decider;

View File

@ -133,7 +133,7 @@ public class MultiSelectManager {
userKeys.add(((ParcelableStatus) item).user_key);
}
}
return userKeys.toArray(new UserKey[userKeys.size()]);
return userKeys.toArray(new UserKey[0]);
}
public interface Callback {

View File

@ -113,7 +113,7 @@ public class NotificationManagerWrapper {
}
private class PostedNotification {
private static class PostedNotification {
private final String tag;
private final int id;

View File

@ -112,13 +112,11 @@ public class RecyclerViewNavigationHelper implements KeyboardShortcutCallback {
public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
final String action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState);
if (action == null) return false;
switch (action) {
case ACTION_NAVIGATION_TOP: {
if (iface != null) {
iface.scrollToStart();
}
return true;
if (ACTION_NAVIGATION_TOP.equals(action)) {
if (iface != null) {
iface.scrollToStart();
}
return true;
}
return false;
}

View File

@ -325,7 +325,7 @@ public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
return false;
}
class PendingDismissData implements Comparable<PendingDismissData> {
static class PendingDismissData implements Comparable<PendingDismissData> {
public int position;
public View view;
@ -391,12 +391,9 @@ public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
lp.height = (Integer) valueAnimator.getAnimatedValue();
dismissView.setLayoutParams(lp);
}
animator.addUpdateListener(valueAnimator -> {
lp.height = (Integer) valueAnimator.getAnimatedValue();
dismissView.setLayoutParams(lp);
});
mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));

View File

@ -25,6 +25,7 @@ package org.mariotaku.twidere.util.collection;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
@ -253,8 +254,7 @@ public class CompactHashSet<E> extends java.util.AbstractSet<E> {
@Override
public void clear() {
elements = 0;
for (int ix = 0; ix < objects.length; ix++)
objects[ix] = null;
Arrays.fill(objects, null);
freecells = objects.length;
modCount++;
}

View File

@ -81,7 +81,7 @@ public class ContentResolverUtils {
public static int bulkInsert(@NonNull final ContentResolver resolver, @NonNull final Uri uri,
@NonNull final Collection<ContentValues> values) {
return bulkInsert(resolver, uri, values.toArray(new ContentValues[values.size()]));
return bulkInsert(resolver, uri, values.toArray(new ContentValues[0]));
}
public static int bulkInsert(@NonNull final ContentResolver resolver, @NonNull final Uri uri,

View File

@ -107,7 +107,7 @@ public final class DatabaseUpgradeHelper {
newInsertColsList.add(newCol);
}
}
final String[] newInsertCols = newInsertColsList.toArray(new String[newInsertColsList.size()]);
final String[] newInsertCols = newInsertColsList.toArray(new String[0]);
if (!TwidereArrayUtils.contains(newInsertCols, notNullCols)) return null;
qb.columns(newInsertCols);
final Columns.Column[] oldDataCols = new Columns.Column[newInsertCols.length];

View File

@ -15,12 +15,7 @@ public class ImgurProvider implements Provider {
public boolean supports(@NonNull String link) {
final String authority = UriUtils.getAuthority(link);
if (authority == null) return false;
switch (authority) {
case "i.imgur.com":
return true;
default:
return false;
}
return "i.imgur.com".equals(authority);
}
@Nullable
@ -28,13 +23,11 @@ public class ImgurProvider implements Provider {
public ParcelableMedia from(@NonNull String url) {
final String authority = UriUtils.getAuthority(url);
if (authority == null) return null;
switch (authority) {
case "i.imgur.com": {
final String path = UriUtils.getPath(url);
if (path == null) return null;
ParcelableMedia media = new ParcelableMedia();
media.url = url;
}
if ("i.imgur.com".equals(authority)) {
final String path = UriUtils.getPath(url);
if (path == null) return null;
ParcelableMedia media = new ParcelableMedia();
media.url = url;
}
return null;
}

View File

@ -47,13 +47,8 @@ public final class ViewSupport {
}
}
@SuppressWarnings("deprecation")
public static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(background);
} else {
ViewAccessorJB.setBackground(view, background);
}
ViewAccessorJB.setBackground(view, background);
}
public static void setButtonTintList(CompoundButton view, ColorStateList list) {
@ -97,8 +92,8 @@ public final class ViewSupport {
if (cls.isAssignableFrom(view.getClass())) return (T) view;
if (view instanceof ViewGroup) {
for (int i = 0, j = ((ViewGroup) view).getChildCount(); i < j; i++) {
final View found = findViewByType(((ViewGroup) view).getChildAt(i), cls);
if (found != null) return (T) found;
final T found = findViewByType(((ViewGroup) view).getChildAt(i), cls);
if (found != null) return found;
}
}
return null;
@ -130,7 +125,6 @@ public final class ViewSupport {
}
static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
view.setBackground(background);
}
}
@ -142,10 +136,8 @@ public final class ViewSupport {
static void setForeground(final View view, final Drawable foreground) {
if (view instanceof FrameLayout) {
//noinspection RedundantCast
((FrameLayout) view).setForeground(foreground);
} else if (view instanceof IForegroundView) {
//noinspection RedundantCast
((IForegroundView) view).setForeground(foreground);
}
}

View File

@ -29,14 +29,12 @@ public class WebSettingsSupport {
}
public static void setAllowUniversalAccessFromFileURLs(final WebSettings settings, final boolean flag) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
WebSettingsAccessorSDK16.setAllowUniversalAccessFromFileURLs(settings, flag);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static class WebSettingsAccessorSDK16 {
private static void setAllowUniversalAccessFromFileURLs(final WebSettings settings, final boolean flag) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
settings.setAllowUniversalAccessFromFileURLs(flag);
}
}

View File

@ -83,7 +83,6 @@ public final class BirthdayView extends LayeredCanvasView {
((AnimatedBitmapLayer) layers[2]).setScale(Math.max(1, w / 160));
}
@SuppressWarnings("deprecation")
@Override
protected boolean fitSystemWindows(@NonNull Rect insets) {
final int stripTop = Utils.INSTANCE.getInsetsTopWithoutActionBarHeight(getContext(), insets.top);

View File

@ -409,13 +409,11 @@ public class HeaderDrawerLayout extends ViewGroup {
if (dy > 0 && mDrawer.canScrollCallback(-dy) && mDrawer.isTouchingScrollableContent()) {
if (!mDrawer.isUsingDragHelper()) {
// Scrolling up while list still has space to scroll, so make header still
mScrollingHeaderByHelper = false;
return current;
} else {
mDrawer.scrollByCallback(-dy);
mScrollingHeaderByHelper = false;
return current;
}
mScrollingHeaderByHelper = false;
return current;
}
final int min = mDrawer.getHeaderTopMinimum(), max = mDrawer.getHeaderTopMaximum();
if (top < min && mDrawer.isTouchingScrollableContent() && mDrawer.isUsingDragHelper()) {

View File

@ -196,17 +196,14 @@ public class ShapedImageView extends AppCompatImageView {
contentHeight = contentBottom - contentTop;
final int size = Math.min(contentWidth, contentHeight);
if (OUTLINE_DRAW) {
drawShape(canvas, mDestination, 0, mBackgroundPaint);
super.onDraw(canvas);
} else {
if (!OUTLINE_DRAW) {
if (mShadowBitmap != null && mDrawShadow) {
canvas.drawBitmap(mShadowBitmap, contentLeft + (contentWidth - size) / 2 - mShadowRadius,
contentTop + (contentHeight - size) / 2 - mShadowRadius, null);
}
drawShape(canvas, mDestination, 0, mBackgroundPaint);
super.onDraw(canvas);
}
drawShape(canvas, mDestination, 0, mBackgroundPaint);
super.onDraw(canvas);
// Then draw the border.
if (mBorderEnabled) {
drawBorder(canvas, mDestination);

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Uses https://github.com/george-steel/android-utils/commit/289aff11e53593a55d780f9f5986e49343a79e55
package org.oshkimaadziig.george.androidutils;
import android.text.Spannable;
@ -33,7 +35,6 @@ import java.util.regex.Pattern;
*
* @author George T. Steel
*/
@SuppressWarnings("IfCanBeSwitch")
public class SpanFormatter {
public static final Pattern FORMAT_SEQUENCE = Pattern.compile("%([0-9]+\\$|<?)([^a-zA-z%]*)([[a-zA-Z%]&&[^tT]]|[tT][a-zA-Z])");
@ -88,10 +89,10 @@ public class SpanFormatter {
if (typeTerm.equals("%")) {
cookedArg = "%";
} else if (typeTerm.equals("%")) {
} else if (typeTerm.equals("n")) {
cookedArg = "\n";
} else {
int argIdx = 0;
int argIdx;
if (argTerm.equals("")) argIdx = ++argAt;
else if (argTerm.equals("<")) argIdx = argAt;
else argIdx = Integer.parseInt(argTerm.substring(0, argTerm.length() - 1)) - 1;

View File

@ -25,26 +25,38 @@ import java.util.*
@SuppressLint("RestrictedApi")
object LocaleHelperAccessor {
fun forLanguageTag(str: String): Locale {
if (str.contains("-")) {
val args = str.split("-").dropLastWhile { it.isEmpty() }.toTypedArray()
if (args.size > 2) {
return Locale(args[0], args[1], args[2])
} else if (args.size > 1) {
return Locale(args[0], args[1])
} else if (args.size == 1) {
return Locale(args[0])
when {
str.contains("-") -> {
val args = str.split("-").dropLastWhile { it.isEmpty() }.toTypedArray()
when {
args.size > 2 -> {
return Locale(args[0], args[1], args[2])
}
args.size > 1 -> {
return Locale(args[0], args[1])
}
args.size == 1 -> {
return Locale(args[0])
}
}
}
} else if (str.contains("_")) {
val args = str.split("_").dropLastWhile { it.isEmpty() }.toTypedArray()
if (args.size > 2) {
return Locale(args[0], args[1], args[2])
} else if (args.size > 1) {
return Locale(args[0], args[1])
} else if (args.size == 1) {
return Locale(args[0])
str.contains("_") -> {
val args = str.split("_").dropLastWhile { it.isEmpty() }.toTypedArray()
when {
args.size > 2 -> {
return Locale(args[0], args[1], args[2])
}
args.size > 1 -> {
return Locale(args[0], args[1])
}
args.size == 1 -> {
return Locale(args[0])
}
}
}
else -> {
return Locale(str)
}
} else {
return Locale(str)
}
throw IllegalArgumentException("Can not parse language tag: [$str]")

View File

@ -19,8 +19,12 @@
package androidx.core.view
fun createWindowInsetsCompat(obj: Any) = WindowInsetsCompat(obj)
import android.annotation.TargetApi
import android.os.Build
import android.view.WindowInsets
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
fun createWindowInsetsCompat(obj: Any) = WindowInsetsCompat.toWindowInsetsCompat(obj as WindowInsets)
val WindowInsetsCompat.unwrapped: Any?
@Suppress("RestrictedApi")
get() = this.toWindowInsets()

View File

@ -1,8 +1,5 @@
package androidx.loader.app
import androidx.loader.app.LoaderManager
import androidx.loader.app.LoaderManagerImpl
/**
* Created by mariotaku on 2016/11/26.
*/

View File

@ -2,7 +2,6 @@ package androidx.loader.content
import android.content.Context
import android.os.AsyncTask
import androidx.loader.content.AsyncTaskLoader
import org.mariotaku.twidere.extension.set
import org.mariotaku.twidere.util.Analyzer

View File

@ -19,6 +19,4 @@
package androidx.recyclerview.widget
import androidx.recyclerview.widget.RecyclerView
val RecyclerView.LayoutManager.recyclerView: RecyclerView? get() = mRecyclerView

View File

@ -10,23 +10,23 @@ import android.os.Handler
fun AccountManager.addOnAccountsUpdatedListenerSafe(listener: OnAccountsUpdateListener,
handler: Handler? = null, updateImmediately: Boolean = false): Boolean {
try {
return try {
this.addOnAccountsUpdatedListener(listener, handler, updateImmediately)
return true
true
} catch (e: IllegalStateException) {
return false
false
} catch (e: IllegalArgumentException) {
return false
false
}
}
fun AccountManager.removeOnAccountsUpdatedListenerSafe(listener: OnAccountsUpdateListener): Boolean {
try {
return try {
this.removeOnAccountsUpdatedListener(listener)
return true
true
} catch (e: IllegalStateException) {
return false
false
} catch (e: IllegalArgumentException) {
return false
false
}
}

View File

@ -13,10 +13,10 @@ fun Collection<*>?.isNullOrEmpty(): Boolean {
}
fun <T> MutableCollection<T>.addAllEnhanced(collection: Collection<T>, ignoreDuplicates: Boolean): Boolean {
if (ignoreDuplicates) {
return addAll(collection.filter { it !in this })
return if (ignoreDuplicates) {
addAll(collection.filter { it !in this })
} else {
return addAll(collection)
addAll(collection)
}
}
@ -41,7 +41,7 @@ fun <E> Collection<E>.contentEquals(other: Collection<E>): Boolean {
inline fun <reified T> List<T>.subArray(range: IntRange): Array<T> {
return Array(range.count()) {
this[range.start + it]
this[range.first + it]
}
}

View File

@ -20,11 +20,11 @@ fun Context.checkAnySelfPermissionsGranted(vararg permissions: String): Boolean
fun Context.unregisterReceiverSafe(receiver: BroadcastReceiver?): Boolean {
if (receiver == null) return false
try {
return try {
unregisterReceiver(receiver)
return true
true
} catch (e: IllegalArgumentException) {
return false
false
}
}

View File

@ -26,7 +26,7 @@ fun Cursor.safeGetInt(columnIndex: Int, def: Int = -1) = try {
def
}
fun Cursor.safeGetString(columnIndex: Int, def: String = "") = try {
fun Cursor.safeGetString(columnIndex: Int, def: String = ""): String = try {
getString(columnIndex)
} catch (e: IllegalStateException) {
def

View File

@ -58,10 +58,10 @@ val Locale.bcp47Tag: String
}
val bcp47Tag = StringBuilder(language)
if (!country.isEmpty()) {
if (country.isNotEmpty()) {
bcp47Tag.append(SEP).append(country)
}
if (!variant.isEmpty()) {
if (variant.isNotEmpty()) {
bcp47Tag.append(SEP).append(variant)
}

View File

@ -48,7 +48,7 @@ fun Number.toLocalizedString(locale: Locale = Locale.getDefault()): String {
val Int.nextPowerOf2: Int
get() {
var n = this
if (n <= 0 || n > 1 shl 30) throw IllegalArgumentException("n is invalid: " + n)
if (n <= 0 || n > 1 shl 30) throw IllegalArgumentException("n is invalid: $n")
n -= 1
n = n or (n shr 16)
n = n or (n shr 8)

View File

@ -6,5 +6,5 @@ import androidx.recyclerview.widget.RecyclerView
* Created by mariotaku on 16/8/21.
*/
fun RecyclerView.Adapter<*>.findPositionByItemId(itemId: Long): Int {
return (0 until itemCount).firstOrNull { getItemId(it) == itemId } ?: androidx.recyclerview.widget.RecyclerView.NO_POSITION
return (0 until itemCount).firstOrNull { getItemId(it) == itemId } ?: RecyclerView.NO_POSITION
}

View File

@ -40,5 +40,5 @@ fun InputStream.expectLine(string: String = "", charset: Charset = Charset.defau
fun InputStream.expectBytes(bytes: ByteArray): Boolean {
val readBytes = ByteArray(bytes.size)
read(readBytes)
return Arrays.equals(readBytes, bytes)
return readBytes.contentEquals(bytes)
}

View File

@ -35,20 +35,24 @@ object InternalActivityCreator {
activity.maxSortPosition = activity.minSortPosition
activity.createdAt = status.getCreatedAt()
if (status.getInReplyToUserId() == accountId) {
activity.action = Activity.Action.REPLY
activity.targetStatuses = arrayOf(status)
when {
status.getInReplyToUserId() == accountId -> {
activity.action = Activity.Action.REPLY
activity.targetStatuses = arrayOf(status)
//TODO set target statuses (in reply to status)
activity.targetObjectStatuses = arrayOfNulls<Status>(0)
} else if (status.quotedStatus?.user?.id == accountId) {
activity.action = Activity.Action.QUOTE
activity.targetStatuses = arrayOf(status)
activity.targetObjectStatuses = arrayOfNulls<Status>(0)
} else {
activity.action = Activity.Action.MENTION
activity.targetUsers = arrayOfNulls<User>(0)
activity.targetObjectStatuses = arrayOf(status)
//TODO set target statuses (in reply to status)
activity.targetObjectStatuses = arrayOfNulls<Status>(0)
}
status.quotedStatus?.user?.id == accountId -> {
activity.action = Activity.Action.QUOTE
activity.targetStatuses = arrayOf(status)
activity.targetObjectStatuses = arrayOfNulls<Status>(0)
}
else -> {
activity.action = Activity.Action.MENTION
activity.targetUsers = arrayOfNulls<User>(0)
activity.targetObjectStatuses = arrayOf(status)
}
}
activity.sourcesSize = 1
activity.sources = arrayOf(status.getUser())

View File

@ -34,7 +34,6 @@ import org.mariotaku.twidere.R
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.model.isOAuth
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils

View File

@ -13,8 +13,7 @@ class AssistLauncherActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
val composeNowAction = prefs.getString(KEY_COMPOSE_NOW_ACTION, VALUE_COMPOSE_NOW_ACTION_COMPOSE)
val action = when (composeNowAction) {
val action = when (prefs.getString(KEY_COMPOSE_NOW_ACTION, VALUE_COMPOSE_NOW_ACTION_COMPOSE)) {
VALUE_COMPOSE_NOW_ACTION_TAKE_PHOTO -> INTENT_ACTION_COMPOSE_TAKE_PHOTO
VALUE_COMPOSE_NOW_ACTION_PICK_IMAGE -> INTENT_ACTION_COMPOSE_PICK_IMAGE
else -> INTENT_ACTION_COMPOSE

View File

@ -27,22 +27,22 @@ import android.graphics.Rect
import android.nfc.NfcAdapter
import android.os.Build
import android.os.Bundle
import androidx.annotation.StyleRes
import androidx.fragment.app.Fragment
import androidx.core.graphics.ColorUtils
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.WindowInsetsCompat
import androidx.appcompat.app.TwilightManagerAccessor
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.appcompat.widget.TwidereActionMenuView
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.appcompat.app.TwilightManagerAccessor
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.appcompat.widget.TwidereActionMenuView
import androidx.core.graphics.ColorUtils
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestManager
import com.squareup.otto.Bus
@ -300,7 +300,7 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
for (i in 0 until handlerFilter.countDataAuthorities()) {
val authorityEntry = handlerFilter.getDataAuthority(i)
val port = authorityEntry.port
intentFilter.addDataAuthority(authorityEntry.host, if (port < 0) null else Integer.toString(port))
intentFilter.addDataAuthority(authorityEntry.host, if (port < 0) null else port.toString())
}
try {
adapter.enableForegroundDispatch(this, intent, arrayOf(intentFilter), null)
@ -363,7 +363,11 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
super.attachBaseContext(newBase)
return
}
super.attachBaseContext(newBase.overriding(locale))
val newContext = newBase.overriding(locale)
super.attachBaseContext(newContext)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
applyOverrideConfiguration(newContext.resources.configuration)
}
}
override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BaseActivity) -> Unit): Promise<Unit, Exception> {
@ -465,20 +469,20 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
}
private fun newInstance(name: String, context: Context, attrs: AttributeSet): View? {
try {
return try {
val cls = findClass(name) ?: throw ClassNotFoundException(name)
val constructor = cls.getConstructor(Context::class.java, AttributeSet::class.java)
return constructor.newInstance(context, attrs) as View
constructor.newInstance(context, attrs) as View
} catch (e: InstantiationException) {
return null
null
} catch (e: IllegalAccessException) {
return null
null
} catch (e: InvocationTargetException) {
return null
null
} catch (e: NoSuchMethodException) {
return null
null
} catch (e: ClassNotFoundException) {
return null
null
}
}

View File

@ -69,7 +69,7 @@ class ColorPickerDialogActivity : BaseActivity(), Callback {
companion object {
val RESULT_CLEARED = -2
const val RESULT_CLEARED = -2
}
}

View File

@ -113,6 +113,7 @@ import java.text.Normalizer
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList
import kotlin.math.abs
import android.Manifest.permission as AndroidPermission
@SuppressLint("RestrictedApi")
@ -389,11 +390,15 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_TAKE_PHOTO, REQUEST_PICK_MEDIA -> {
if (resultCode == Activity.RESULT_OK && data != null) {
val src = MediaPickerActivity.getMediaUris(data)
TaskStarter.execute(AddMediaTask(this, src, null, false, false))
TaskStarter.execute(AddMediaTask(this, src, null,
copySrc = false,
deleteSrc = false
))
val extras = data.getBundleExtra(MediaPickerActivity.EXTRA_EXTRAS)
if (extras?.getBoolean(EXTRA_IS_POSSIBLY_SENSITIVE) == true) {
possiblySensitive = true
@ -430,7 +435,10 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
val src = MediaPickerActivity.getMediaUris(data)?.takeIf(Array<Uri>::isNotEmpty) ?:
data.getParcelableExtra<Uri>(EXTRA_IMAGE_URI)?.let { arrayOf(it) }
if (src != null) {
TaskStarter.execute(AddMediaTask(this, src, null, false, false))
TaskStarter.execute(AddMediaTask(this, src, null,
copySrc = false,
deleteSrc = false
))
}
}
}
@ -508,7 +516,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
replyLabel -> {
if (replyLabel.visibility != View.VISIBLE) return
replyLabel.setSingleLine(replyLabel.lineCount > 1)
replyLabel.isSingleLine = replyLabel.lineCount > 1
}
}
}
@ -806,8 +814,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
private fun extensionIntentItemSelected(item: MenuItem) {
val intent = item.intent ?: return
try {
val action = intent.action
when (action) {
when (intent.action) {
INTENT_ACTION_EXTENSION_COMPOSE -> {
val accountKeys = accountsAdapter.selectedAccountKeys
intent.putExtra(EXTRA_TEXT, ParseUtils.parseString(editText.text))
@ -1083,16 +1090,20 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
val action = intent.action
val hasVisibility = intent.hasExtra(EXTRA_VISIBILITY)
val hasAccountKeys: Boolean
if (intent.hasExtra(EXTRA_ACCOUNT_KEYS)) {
val accountKeys = intent.getTypedArrayExtra<UserKey>(EXTRA_ACCOUNT_KEYS)
accountsAdapter.selectedAccountKeys = accountKeys
hasAccountKeys = true
} else if (intent.hasExtra(EXTRA_ACCOUNT_KEY)) {
val accountKey = intent.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
accountsAdapter.selectedAccountKeys = arrayOf(accountKey)
hasAccountKeys = true
} else {
hasAccountKeys = false
when {
intent.hasExtra(EXTRA_ACCOUNT_KEYS) -> {
val accountKeys = intent.getTypedArrayExtra<UserKey>(EXTRA_ACCOUNT_KEYS)
accountsAdapter.selectedAccountKeys = accountKeys
hasAccountKeys = true
}
intent.hasExtra(EXTRA_ACCOUNT_KEY) -> {
val accountKey = intent.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
accountsAdapter.selectedAccountKeys = arrayOf(accountKey)
hasAccountKeys = true
}
else -> {
hasAccountKeys = false
}
}
when (action) {
Intent.ACTION_SEND, Intent.ACTION_SEND_MULTIPLE -> {
@ -1101,7 +1112,10 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
val stream = intent.getStreamExtra()
if (stream != null) {
val src = stream.toTypedArray()
TaskStarter.execute(AddMediaTask(this, src, null, true, false))
TaskStarter.execute(AddMediaTask(this, src, null,
copySrc = true,
deleteSrc = false
))
}
}
else -> {
@ -1110,7 +1124,10 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
val data = intent.data
if (data != null) {
val src = arrayOf(data)
TaskStarter.execute(AddMediaTask(this, src, null, true, false))
TaskStarter.execute(AddMediaTask(this, src, null,
copySrc = true,
deleteSrc = false
))
}
}
}
@ -1146,16 +1163,16 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
INTENT_ACTION_EDIT_DRAFT -> {
val draft: Draft? = intent.getParcelableExtra(EXTRA_DRAFT)
when (draft?.action_type) {
return when (draft?.action_type) {
Draft.Action.REPLY -> {
return showReplyLabelAndHint((draft.action_extras as? UpdateStatusActionExtras)?.inReplyToStatus)
showReplyLabelAndHint((draft.action_extras as? UpdateStatusActionExtras)?.inReplyToStatus)
}
Draft.Action.QUOTE -> {
return showQuoteLabelAndHint((draft.action_extras as? UpdateStatusActionExtras)?.inReplyToStatus)
showQuoteLabelAndHint((draft.action_extras as? UpdateStatusActionExtras)?.inReplyToStatus)
}
else -> {
showDefaultLabelAndHint()
return false
false
}
}
}
@ -1785,7 +1802,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
s.setSpan(MarkForDeleteSpan(), start, start + count,
Spanned.SPAN_INCLUSIVE_INCLUSIVE)
}
if (!imageSources.isEmpty()) {
if (imageSources.isNotEmpty()) {
val intent = ThemedMediaPickerActivity.withThemed(this@ComposeActivity)
.getMedia(Uri.parse(imageSources[0]))
.build()
@ -1816,7 +1833,10 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
})
editText.customSelectionActionModeCallback = this
editText.imageInputListener = { contentInfo ->
val task = AddMediaTask(this, arrayOf(contentInfo.contentUri), null, true, false)
val task = AddMediaTask(this, arrayOf(contentInfo.contentUri), null,
copySrc = true,
deleteSrc = false
)
task.callback = {
contentInfo.releasePermission()
}
@ -1839,8 +1859,8 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val context = activity!!
val builder = AlertDialog.Builder(context!!)
val context = requireActivity()
val builder = AlertDialog.Builder(requireContext())
builder.setMessage(R.string.quote_protected_status_warning_message)
builder.setPositiveButton(R.string.send_anyway, this)
builder.setNegativeButton(android.R.string.cancel, null)
@ -1873,8 +1893,8 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val context = activity!!
val builder = AlertDialog.Builder(context!!)
val context = requireActivity()
val builder = AlertDialog.Builder(requireContext())
builder.setMessage(getString(R.string.message_format_compose_message_convert_to_status,
"@$screenName"))
builder.setPositiveButton(R.string.action_send, this)
@ -1886,7 +1906,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
}
class AttachedMediaItemTouchHelperCallback(adapter: SimpleItemTouchHelperCallback.ItemTouchHelperAdapter) : SimpleItemTouchHelperCallback(adapter) {
class AttachedMediaItemTouchHelperCallback(adapter: ItemTouchHelperAdapter) : SimpleItemTouchHelperCallback(adapter) {
override fun isLongPressDragEnabled(): Boolean {
return true
@ -1906,7 +1926,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
// Fade out the view as it is swiped out of the parent's bounds
val alpha = ALPHA_FULL - Math.abs(dY) / viewHolder.itemView.height.toFloat()
val alpha = ALPHA_FULL - abs(dY) / viewHolder.itemView.height.toFloat()
viewHolder.itemView.alpha = alpha
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
} else {
@ -1924,7 +1944,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
}
companion object {
val ALPHA_FULL = 1.0f
const val ALPHA_FULL = 1.0f
}
}
@ -1996,7 +2016,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
set(value) {
selection.clear()
for (accountKey in value) {
selection.put(accountKey, true)
selection[accountKey] = true
}
notifyDataSetChanged()
}
@ -2034,7 +2054,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
fun toggleSelection(position: Int) {
if (accounts == null || position < 0) return
val account = accounts!![position]
selection.put(account.key, true != selection[account.key])
selection[account.key] = true != selection[account.key]
activity.updateAccountSelectionState()
activity.updateVisibilityState()
activity.updateSummaryTextState()
@ -2046,7 +2066,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
if (accounts == null || position < 0) return
val account = accounts!![position]
selection.clear()
selection.put(account.key, true != selection[account.key])
selection[account.key] = true != selection[account.key]
activity.updateAccountSelectionState()
activity.updateVisibilityState()
activity.updateSummaryTextState()
@ -2096,12 +2116,12 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
private class DisplayPlaceNameTask : AbstractTask<ParcelableLocation, List<Address>, ComposeActivity>() {
override fun doLongOperation(location: ParcelableLocation): List<Address>? {
try {
return try {
val activity = callback ?: throw IOException("Interrupted")
val gcd = Geocoder(activity, Locale.getDefault())
return gcd.getFromLocation(location.latitude, location.longitude, 1)
gcd.getFromLocation(location.latitude, location.longitude, 1)
} catch (e: IOException) {
return null
null
}
}
@ -2119,13 +2139,16 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
textView.spannable = ParcelableLocationUtils.getHumanReadableString(location, 3)
textView.tag = location
} else {
val tag = textView.tag
if (tag is Address) {
textView.spannable = tag.locality
} else if (tag is NoAddress) {
textView.setText(R.string.label_location_your_coarse_location)
} else {
textView.setText(R.string.getting_location)
when (val tag = textView.tag) {
is Address -> {
textView.spannable = tag.locality
}
is NoAddress -> {
textView.setText(R.string.label_location_your_coarse_location)
}
else -> {
textView.setText(R.string.getting_location)
}
}
}
} else {

View File

@ -105,12 +105,12 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
?: return false
// val file = File(folder, fileName)
// file.delete()
try {
return try {
DataImportExportUtils.exportData(activity, file, flags)
return true
true
} catch (e: IOException) {
Log.w(LOGTAG, e)
return false
false
}
}
@ -134,7 +134,7 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
companion object {
private val FRAGMENT_TAG = "import_settings_dialog"
private const val FRAGMENT_TAG = "import_settings_dialog"
}
}

View File

@ -111,12 +111,12 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
return false
}
if (!file.isFile) return false
try {
return try {
DataImportExportUtils.importData(activity, file, flags)
return true
true
} catch (e: IOException) {
Log.w(LOGTAG, e)
return false
false
}
}
@ -140,7 +140,7 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
companion object {
private val FRAGMENT_TAG = "import_settings_dialog"
private const val FRAGMENT_TAG = "import_settings_dialog"
}
}
@ -152,10 +152,10 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
return 0
}
if (!file.isFile) return 0
try {
return DataImportExportUtils.getImportedSettingsFlags(activity, file)
return try {
DataImportExportUtils.getImportedSettingsFlags(activity, file)
} catch (e: IOException) {
return 0
0
}
}
@ -185,7 +185,7 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
companion object {
private val FRAGMENT_TAG = "read_settings_data_dialog"
private const val FRAGMENT_TAG = "read_settings_data_dialog"
}
}

View File

@ -87,13 +87,17 @@ class FileSelectorActivity : BaseActivity(), FileSelectorDialogFragment.Callback
finish()
return
}
if (checkAllSelfPermissionsGranted(AndroidPermissions.READ_EXTERNAL_STORAGE, AndroidPermissions.WRITE_EXTERNAL_STORAGE)) {
showPickFileDialog()
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
val permissions = arrayOf(AndroidPermissions.READ_EXTERNAL_STORAGE, AndroidPermissions.WRITE_EXTERNAL_STORAGE)
ActivityCompat.requestPermissions(this, permissions, REQUEST_REQUEST_PERMISSIONS)
} else {
finishWithDeniedMessage()
when {
checkAllSelfPermissionsGranted(AndroidPermissions.READ_EXTERNAL_STORAGE, AndroidPermissions.WRITE_EXTERNAL_STORAGE) -> {
showPickFileDialog()
}
Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN -> {
val permissions = arrayOf(AndroidPermissions.READ_EXTERNAL_STORAGE, AndroidPermissions.WRITE_EXTERNAL_STORAGE)
ActivityCompat.requestPermissions(this, permissions, REQUEST_REQUEST_PERMISSIONS)
}
else -> {
finishWithDeniedMessage()
}
}
}

View File

@ -107,6 +107,7 @@ import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.view.HomeDrawerLayout
import org.mariotaku.twidere.view.TabPagerIndicator
import java.lang.ref.WeakReference
import kotlin.math.floor
class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, SupportFragmentCallback,
OnLongClickListener, DrawerLayout.DrawerListener {
@ -422,12 +423,18 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
if (!ViewCompat.getFitsSystemWindows(homeMenu)) {
homeContent.setPadding(0, insets.systemWindowInsetTop, 0, 0)
}
(toolbar.layoutParams as? MarginLayoutParams)?.bottomMargin = insets.systemWindowInsetBottom
(actionsButton.layoutParams as? MarginLayoutParams)?.bottomMargin =
actionsButtonBottomMargin + insets.systemWindowInsetBottom
actionsButtonBottomMargin + if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
insets.systemWindowInsetBottom
} else {
0
}
return insets
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val tabPosition = handleIntent(intent, false)
if (tabPosition >= 0) {
mainPager.currentItem = tabPosition.coerceInOr(0 until pagerAdapter.count, 0)
@ -623,16 +630,22 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
}
notifyControlBarOffsetChanged()
} else {
val layoutparams = toolbar.layoutParams
val toolbarMarginBottom = if (layoutparams is MarginLayoutParams) {
layoutparams.bottomMargin
} else {
0
}
val translationY = if (mainTabs.columns > 1 || !toolbar.isVisible) {
0
} else {
(toolbar.height * (offset - 1)).toInt()
((toolbar.height + toolbarMarginBottom) * (offset - 1)).toInt()
}
toolbar.translationY = -translationY.toFloat()
windowOverlay.translationY = -translationY.toFloat()
val lp = actionsButton.layoutParams
if (lp is MarginLayoutParams) {
actionsButton.translationY = (lp.bottomMargin + toolbar.height + actionsButton.height) * (1 - offset)
actionsButton.translationY = (lp.bottomMargin + toolbar.height + actionsButton.height + toolbarMarginBottom) * (1 - offset)
} else {
actionsButton.translationY = actionsButton.height * (1 - offset)
}
@ -848,7 +861,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
"wide" -> resources.getDimension(R.dimen.preferred_tab_column_width_wide)
else -> resources.getDimension(R.dimen.preferred_tab_column_width_normal)
}
mainTabs.columns = Math.floor(1.0 / pagerAdapter.getPageWidth(0)).toInt()
mainTabs.columns = floor(1.0 / pagerAdapter.getPageWidth(0)).toInt()
} else {
mainPager.pageMargin = 0
mainPager.setPageMarginDrawable(null)
@ -1059,7 +1072,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
class AutoRefreshConfirmDialogFragment : BaseDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.auto_refresh)
builder.setMessage(R.string.message_auto_refresh_confirm)
builder.setPositiveButton(android.R.string.ok) { _, _ ->

View File

@ -171,7 +171,7 @@ class ImageCropperActivity : BaseActivity(), CropImageView.OnSetImageUriComplete
private fun getResultIntent(uri: Uri?, error: Exception?, sampleSize: Int): Intent {
val result = CropImage.ActivityResult(cropImageView.imageUri, uri, error,
cropImageView.cropPoints, cropImageView.cropRect, cropImageView.rotatedDegrees,
sampleSize)
cropImageView.wholeImageRect, sampleSize)
val intent = Intent()
intent.putExtra(CropImage.CROP_IMAGE_EXTRA_RESULT, result)
return intent

View File

@ -30,7 +30,7 @@ class InvalidAccountAlertActivity : FragmentActivity() {
class InvalidAccountAlertDialogFragment : BaseDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.title_error_invalid_account)
builder.setMessage(R.string.message_error_invalid_account)
builder.setPositiveButton(android.R.string.ok) { _, _ ->

View File

@ -119,7 +119,7 @@ class KeyboardShortcutPreferenceCompatActivity : BaseActivity(), OnClickListener
companion object {
val EXTRA_CONTEXT_TAG = "context_tag"
val EXTRA_KEY_ACTION = "key_action"
const val EXTRA_CONTEXT_TAG = "context_tag"
const val EXTRA_KEY_ACTION = "key_action"
}
}

View File

@ -26,7 +26,6 @@ import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Parcelable
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
@ -75,6 +74,8 @@ import org.mariotaku.twidere.view.viewer.MediaSwipeCloseContainer
import java.io.File
import javax.inject.Inject
import kotlin.concurrent.thread
import kotlin.math.abs
import kotlin.math.roundToInt
import android.Manifest.permission as AndroidPermissions
class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeCloseContainer.Listener,
@ -146,7 +147,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
activityLayout.statusBarAlpha = offset
}
try {
actionBar.hideOffset = Math.round(controlBarHeight * (1f - offset))
actionBar.hideOffset = (controlBarHeight * (1f - offset)).roundToInt()
} catch (e: UnsupportedOperationException) {
// Some device will throw this exception
hideOffsetNotSupported = true
@ -181,6 +182,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_SHARE_MEDIA -> {
ShareProvider.clearTempFiles(this)
@ -367,10 +369,10 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
ParcelableMedia.Type.IMAGE -> {
val mediaUrl = media.media_url ?: return Fragment.instantiate(this, ExternalBrowserPageFragment::class.java.name, args) as MediaViewerFragment
args.putParcelable(EXTRA_MEDIA_URI, Uri.parse(mediaUrl))
if (mediaUrl.endsWith(".gif")) {
return Fragment.instantiate(this, GifPageFragment::class.java.name, args) as MediaViewerFragment
return if (mediaUrl.endsWith(".gif")) {
Fragment.instantiate(this, GifPageFragment::class.java.name, args) as MediaViewerFragment
} else {
return Fragment.instantiate(this, ImagePageFragment::class.java.name, args) as MediaViewerFragment
Fragment.instantiate(this, ImagePageFragment::class.java.name, args) as MediaViewerFragment
}
}
ParcelableMedia.Type.ANIMATED_GIF, ParcelableMedia.Type.CARD_ANIMATED_GIF -> {
@ -408,10 +410,10 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
}
override fun onSwipeOffsetChanged(offset: Int) {
val offsetFactor = 1 - (Math.abs(offset).toFloat() / swipeContainer.height)
val offsetFactor = 1 - (abs(offset).toFloat() / swipeContainer.height)
swipeContainer.backgroundAlpha = offsetFactor
val colorToolbar = overrideTheme.colorToolbar
val alpha = Math.round(Color.alpha(colorToolbar) * offsetFactor).coerceIn(0..255)
val alpha = (Color.alpha(colorToolbar) * offsetFactor).roundToInt().coerceIn(0..255)
activityLayout.statusBarAlpha = alpha / 255f
}
@ -450,11 +452,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
}
private fun instantiateMediaViewerFragment(args: Bundle): MediaViewerFragment {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
Fragment.instantiate(this, VideoPageFragment::class.java.name, args) as MediaViewerFragment
} else {
Fragment.instantiate(this, ExoPlayerPageFragment::class.java.name, args) as MediaViewerFragment
}
return Fragment.instantiate(this, ExoPlayerPageFragment::class.java.name, args) as MediaViewerFragment
}
private fun processShareIntent(intent: Intent) {
@ -468,11 +466,10 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
if (checkAllSelfPermissionsGranted(AndroidPermissions.WRITE_EXTERNAL_STORAGE)) {
saveToStorage()
} else {
val permissions: Array<String>
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
permissions = arrayOf(AndroidPermissions.WRITE_EXTERNAL_STORAGE, AndroidPermissions.READ_EXTERNAL_STORAGE)
val permissions: Array<String> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
arrayOf(AndroidPermissions.WRITE_EXTERNAL_STORAGE, AndroidPermissions.READ_EXTERNAL_STORAGE)
} else {
permissions = arrayOf(AndroidPermissions.WRITE_EXTERNAL_STORAGE)
arrayOf(AndroidPermissions.WRITE_EXTERNAL_STORAGE)
}
PermissionRequestDialog.show(supportFragmentManager, getString(R.string.message_permission_request_save_media),
permissions, REQUEST_PERMISSION_SAVE_MEDIA)
@ -503,8 +500,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
private fun saveToStorage() {
val fileInfo = getCurrentCacheFileInfo(saveToStoragePosition) ?: return
val type = (fileInfo as? CacheProvider.CacheFileTypeSupport)?.cacheFileType
val pubDir = when (type) {
val pubDir = when ((fileInfo as? CacheProvider.CacheFileTypeSupport)?.cacheFileType) {
CacheFileType.VIDEO -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
@ -640,10 +636,10 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
companion object {
private val REQUEST_SHARE_MEDIA = 201
private val REQUEST_PERMISSION_SAVE_MEDIA = 202
private val REQUEST_PERMISSION_SHARE_MEDIA = 203
private val REQUEST_SELECT_SAVE_MEDIA = 204
private const val REQUEST_SHARE_MEDIA = 201
private const val REQUEST_PERMISSION_SAVE_MEDIA = 202
private const val REQUEST_PERMISSION_SHARE_MEDIA = 203
private const val REQUEST_SELECT_SAVE_MEDIA = 204
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
const val FLAG_SYSTEM_UI_HIDE_BARS = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or

View File

@ -89,6 +89,7 @@ class PremiumDashboardActivity : BaseActivity() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (resultCode) {
REQUEST_PURCHASE_EXTRA_FEATURES -> {
if (resultCode == Activity.RESULT_OK) {

View File

@ -171,7 +171,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
override fun onDismiss(listView: ListView, reverseSortedPositions: IntArray) {
val adapter = suggestionsList.adapter as SuggestionsAdapter
val ids = LongArray(reverseSortedPositions.size)
for (i in 0 until reverseSortedPositions.size) {
for (i in reverseSortedPositions.indices) {
val position = reverseSortedPositions[i]
val item = adapter.getSuggestionItem(position) ?: return
ids[i] = item._id
@ -215,6 +215,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_SCAN_QR -> {
if (resultCode == Activity.RESULT_OK && data != null) {
@ -504,7 +505,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
private fun getActualPosition(position: Int): Int {
var skipped = 0
for (i in 0 until removedPositions.size) {
if (position + skipped >= removedPositions.get(i)) {
if (position + skipped >= removedPositions[i]) {
skipped++
}
}
@ -537,10 +538,10 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
companion object {
internal val VIEW_TYPE_SEARCH_HISTORY = 0
internal val VIEW_TYPE_SAVED_SEARCH = 1
internal val VIEW_TYPE_USER_SUGGESTION_ITEM = 2
internal val VIEW_TYPE_USER_SCREEN_NAME = 3
internal const val VIEW_TYPE_SEARCH_HISTORY = 0
internal const val VIEW_TYPE_SAVED_SEARCH = 1
internal const val VIEW_TYPE_USER_SUGGESTION_ITEM = 2
internal const val VIEW_TYPE_USER_SCREEN_NAME = 3
}
}

View File

@ -54,6 +54,7 @@ import org.mariotaku.twidere.util.DeviceUtils
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.ThemeUtils
import java.util.*
import kotlin.system.exitProcess
class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartFragmentCallback {
@ -74,8 +75,7 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
shouldTerminate = savedInstanceState.getBoolean(EXTRA_SHOULD_TERMINATE, shouldTerminate)
} else if (intent.getBooleanExtra(EXTRA_SHOULD_TERMINATE, false)) {
finishNoRestart()
System.exit(0)
return
exitProcess(0)
}
val backgroundOption = currentThemeBackgroundOption
@ -349,8 +349,8 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
companion object {
val VIEW_TYPE_PREFERENCE_ENTRY = 0
val VIEW_TYPE_HEADER_ENTRY = 1
const val VIEW_TYPE_PREFERENCE_ENTRY = 0
const val VIEW_TYPE_HEADER_ENTRY = 1
}
}
@ -388,7 +388,7 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
class RestartConfirmDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(activity!!)
val builder = AlertDialog.Builder(requireActivity())
if (arguments?.getBoolean(EXTRA_SHOULD_TERMINATE) == true) {
builder.setMessage(R.string.app_terminate_confirm)
builder.setNegativeButton(R.string.action_dont_terminate, this)
@ -424,7 +424,7 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
companion object {
private val RESULT_SETTINGS_CHANGED = 10
private const val RESULT_SETTINGS_CHANGED = 10
fun setShouldRecreate(activity: Activity) {
if (activity !is SettingsActivity) return

View File

@ -428,23 +428,30 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
internal fun onSignInError(exception: Exception) {
DebugLog.w(LOGTAG, "Sign in error", exception)
var errorReason: String? = null
if (exception is AuthenticityTokenException) {
Toast.makeText(this, R.string.message_toast_wrong_api_key, Toast.LENGTH_SHORT).show()
errorReason = "wrong_api_key"
} else if (exception is WrongUserPassException) {
Toast.makeText(this, R.string.message_toast_wrong_username_password, Toast.LENGTH_SHORT).show()
errorReason = "wrong_username_password"
} else if (exception is SignInTask.WrongBasicCredentialException) {
Toast.makeText(this, R.string.message_toast_wrong_username_password, Toast.LENGTH_SHORT).show()
errorReason = "wrong_username_password"
} else if (exception is SignInTask.WrongAPIURLFormatException) {
Toast.makeText(this, R.string.message_toast_wrong_api_key, Toast.LENGTH_SHORT).show()
errorReason = "wrong_api_key"
} else if (exception is LoginVerificationException) {
Toast.makeText(this, R.string.message_toast_login_verification_failed, Toast.LENGTH_SHORT).show()
errorReason = "login_verification_failed"
} else {
Toast.makeText(this, exception.getErrorMessage(this), Toast.LENGTH_SHORT).show()
when (exception) {
is AuthenticityTokenException -> {
Toast.makeText(this, R.string.message_toast_wrong_api_key, Toast.LENGTH_SHORT).show()
errorReason = "wrong_api_key"
}
is WrongUserPassException -> {
Toast.makeText(this, R.string.message_toast_wrong_username_password, Toast.LENGTH_SHORT).show()
errorReason = "wrong_username_password"
}
is SignInTask.WrongBasicCredentialException -> {
Toast.makeText(this, R.string.message_toast_wrong_username_password, Toast.LENGTH_SHORT).show()
errorReason = "wrong_username_password"
}
is SignInTask.WrongAPIURLFormatException -> {
Toast.makeText(this, R.string.message_toast_wrong_api_key, Toast.LENGTH_SHORT).show()
errorReason = "wrong_api_key"
}
is LoginVerificationException -> {
Toast.makeText(this, R.string.message_toast_login_verification_failed, Toast.LENGTH_SHORT).show()
errorReason = "login_verification_failed"
}
else -> {
Toast.makeText(this, exception.getErrorMessage(this), Toast.LENGTH_SHORT).show()
}
}
Analyzer.log(SignIn(false, credentialsType = apiConfig.credentialsType,
errorReason = errorReason, accountType = apiConfig.type))
@ -573,13 +580,13 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
class SignInTypeChooserDialogFragment : BaseDialogFragment(),
LoaderManager.LoaderCallbacks<List<CustomAPIConfig>> {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
val builder = AlertDialog.Builder(requireContext())
builder.setView(R.layout.dialog_expandable_list)
val dialog = builder.create()
dialog.onShow {
it.applyTheme()
val listView = it.expandableList
val adapter = LoginTypeAdapter(context!!)
val adapter = LoginTypeAdapter(requireContext())
listView.setAdapter(adapter)
listView.setOnGroupClickListener { _, _, groupPosition, _ ->
val type = adapter.getGroup(groupPosition)
@ -623,7 +630,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
AccountType.MASTODON, AccountType.STATUSNET)
val result = supportedAccountTypes.mapNotNullTo(ArrayList()) { type ->
if (type == AccountType.MASTODON) return@mapNotNullTo LoginType(type,
listOf(CustomAPIConfig.mastodon(context!!)))
listOf(CustomAPIConfig.mastodon(requireContext())))
return@mapNotNullTo configGroup[type]?.let { list ->
LoginType(type, list.sortedBy { !it.isDefault })
}
@ -632,7 +639,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<CustomAPIConfig>> {
return DefaultAPIConfigLoader(context!!)
return DefaultAPIConfigLoader(requireContext())
}
override fun onLoaderReset(loader: Loader<List<CustomAPIConfig>>) {
@ -694,7 +701,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
var challengeType: String? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.login_verification)
builder.setView(R.layout.dialog_login_verification_code)
builder.positive(android.R.string.ok, this::performVerification)
@ -753,7 +760,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
class PasswordSignInDialogFragment : BaseDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
val builder = AlertDialog.Builder(requireContext())
builder.setView(R.layout.dialog_password_sign_in)
builder.positive(R.string.action_sign_in, this::onPositiveButton)
builder.setNegativeButton(android.R.string.cancel, null)
@ -809,10 +816,10 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val oauth = newMicroBlogInstance(context, endpoint = endpoint, auth = auth,
accountType = apiConfig.type, cls = TwitterOAuth::class.java)
val accessToken: OAuthToken
if (oauthVerifier != null) {
accessToken = oauth.getAccessToken(requestToken, oauthVerifier)
accessToken = if (oauthVerifier != null) {
oauth.getAccessToken(requestToken, oauthVerifier)
} else {
accessToken = oauth.getAccessToken(requestToken)
oauth.getAccessToken(requestToken)
}
auth = apiConfig.getOAuthAuthorization(accessToken) ?:
throw MicroBlogException("Invalid OAuth credential")
@ -823,7 +830,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
accountType = apiConfig.type, cls = MicroBlog::class.java)
val apiUser = twitter.verifyCredentials()
var color = analyseUserProfileColor(apiUser)
val (type, extras) = SignInActivity.detectAccountType(twitter, apiUser, apiConfig.type)
val (type, extras) = detectAccountType(twitter, apiUser, apiConfig.type)
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(context)
@ -901,7 +908,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
return authOAuth()
}
@Throws(OAuthPasswordAuthenticator.AuthenticationException::class, MicroBlogException::class)
@Throws(AuthenticationException::class, MicroBlogException::class)
private fun authOAuth(): SignInResponse {
val activity = activityRef.get() ?: throw InterruptedException()
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat,
@ -940,7 +947,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
return getOAuthSignInResponse(activity, accessToken, Credentials.Type.XAUTH)
}
@Throws(MicroBlogException::class, OAuthPasswordAuthenticator.AuthenticationException::class)
@Throws(MicroBlogException::class, AuthenticationException::class)
private fun authBasic(): SignInResponse {
val activity = activityRef.get() ?: throw InterruptedException()
val versionSuffix = if (apiConfig.isNoVersionSuffix) null else "1.1"
@ -962,7 +969,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
}
var color = analyseUserProfileColor(apiUser)
val (type, extras) = SignInActivity.detectAccountType(twitter, apiUser, apiConfig.type)
val (type, extras) = detectAccountType(twitter, apiUser, apiConfig.type)
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
@ -991,7 +998,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
accountType = apiConfig.type, cls = MicroBlog::class.java)
val apiUser = twitter.verifyCredentials()
var color = analyseUserProfileColor(apiUser)
val (type, extras) = SignInActivity.detectAccountType(twitter, apiUser, apiConfig.type)
val (type, extras) = detectAccountType(twitter, apiUser, apiConfig.type)
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
@ -1018,7 +1025,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
accountType = apiConfig.type, cls = MicroBlog::class.java)
val apiUser = twitter.verifyCredentials()
var color = analyseUserProfileColor(apiUser)
val (type, extras) = SignInActivity.detectAccountType(twitter, apiUser, apiConfig.type)
val (type, extras) = detectAccountType(twitter, apiUser, apiConfig.type)
val accountKey = apiUser.key
val user = apiUser.toParcelable(accountKey, type, profileImageSize = profileImageSize)
val am = AccountManager.get(activity)
@ -1040,11 +1047,11 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
return SignInResponse(account != null, authType, credentials, user, color, type, extras)
}
internal class WrongBasicCredentialException : OAuthPasswordAuthenticator.AuthenticationException()
internal class WrongBasicCredentialException : AuthenticationException()
internal class WrongAPIURLFormatException : OAuthPasswordAuthenticator.AuthenticationException()
internal class WrongAPIURLFormatException : AuthenticationException()
internal inner class InputLoginVerificationCallback : OAuthPasswordAuthenticator.LoginVerificationCallback {
internal inner class InputLoginVerificationCallback : LoginVerificationCallback {
override fun getLoginVerification(challengeType: String): String? {
// Dismiss current progress dialog
@ -1087,10 +1094,10 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
protected val profileImageSize: String = activity.getString(R.string.profile_image_size)
final override fun doInBackground(vararg args: Any?): SingleResponse<SignInResponse> {
try {
return SingleResponse.getInstance(performLogin())
return try {
SingleResponse.getInstance(performLogin())
} catch (e: Exception) {
return SingleResponse.getInstance(e)
SingleResponse.getInstance(e)
}
}
@ -1189,8 +1196,8 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
const val REQUEST_BROWSER_TWITTER_SIGN_IN = 101
const val REQUEST_BROWSER_MASTODON_SIGN_IN = 102
private val FRAGMENT_TAG_SIGN_IN_PROGRESS = "sign_in_progress"
private val EXTRA_API_LAST_CHANGE = "api_last_change"
private const val FRAGMENT_TAG_SIGN_IN_PROGRESS = "sign_in_progress"
private const val EXTRA_API_LAST_CHANGE = "api_last_change"
@Throws(IOException::class)
internal fun detectAccountType(twitter: MicroBlog, user: User, type: String?): Pair<String, AccountExtras?> {

View File

@ -41,8 +41,8 @@ class ThemedMediaPickerActivity : MediaPickerActivity() {
companion object {
fun withThemed(context: Context): MediaPickerActivity.IntentBuilder {
val builder = MediaPickerActivity.IntentBuilder(context, ThemedMediaPickerActivity::class.java)
fun withThemed(context: Context): IntentBuilder {
val builder = IntentBuilder(context, ThemedMediaPickerActivity::class.java)
builder.cropImageActivityClass(ImageCropperActivity::class.java)
builder.streamDownloaderClass(RestFuNetworkStreamDownloader::class.java)
return builder

View File

@ -93,7 +93,7 @@ class TrendsLocationSelectorActivity : BaseActivity() {
private val list: Array<LocationsMap.LocationsData> get() = arguments?.getTypedArray(EXTRA_DATA) ?: emptyArray()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val selectorBuilder = AlertDialog.Builder(context!!)
val selectorBuilder = AlertDialog.Builder(requireContext())
selectorBuilder.setTitle(R.string.trends_location)
selectorBuilder.setView(R.layout.dialog_expandable_list)
selectorBuilder.setNegativeButton(android.R.string.cancel, null)
@ -101,7 +101,7 @@ class TrendsLocationSelectorActivity : BaseActivity() {
dialog.onShow {
it.applyTheme()
val listView = it.expandableList
val adapter = ExpandableTrendLocationsListAdapter(context!!)
val adapter = ExpandableTrendLocationsListAdapter(requireContext())
adapter.data = list
listView.setAdapter(adapter)
listView.setOnGroupClickListener(ExpandableListView.OnGroupClickListener { _, _, groupPosition, _ ->
@ -177,23 +177,14 @@ class TrendsLocationSelectorActivity : BaseActivity() {
}
override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup): View {
val view: View
if (convertView != null) {
view = convertView
} else {
view = inflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false)
}
val view: View = convertView ?: inflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false)
view.findViewById<TextView>(android.R.id.text1).text = getGroup(groupPosition).name
return view
}
override fun getChildView(groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup): View {
val view: View
if (convertView != null) {
view = convertView
} else {
view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
}
val view: View =
convertView ?: inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
val location = getChild(groupPosition, childPosition)
val text1 = view.findViewById<TextView>(android.R.id.text1)
if (location.parentId == WORLDWIDE) {

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