diff --git a/settings.gradle b/settings.gradle index 8a9edf394..c7290ea6f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ -include ':twidere', ':twidere.wear' +include ':twidere', ':twidere.wear', ':twidere.donate.nyanwp', ':twidere.nyan', ':twidere.donate.nyanwp.wear' include ':SlidingMenu', ':DragSortListView', ':MenuComponent', ':RefreshNow', ':PullToRefresh', ':MessageBubbleView' project(':SlidingMenu').projectDir = file('libraries/SlidingMenu/library') diff --git a/twidere.donate.nyanwp.wear/.gitignore b/twidere.donate.nyanwp.wear/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/twidere.donate.nyanwp.wear/.gitignore @@ -0,0 +1 @@ +/build diff --git a/twidere.donate.nyanwp.wear/build.gradle b/twidere.donate.nyanwp.wear/build.gradle new file mode 100644 index 000000000..6b62cddf7 --- /dev/null +++ b/twidere.donate.nyanwp.wear/build.gradle @@ -0,0 +1,80 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +apply plugin: 'com.android.application' + + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.mariotaku.twidere.donate.nyanwp" + minSdkVersion 20 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + signingConfigs { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.debug.storeFile")) + storePassword signingProp.get("twidere.debug.storePassword") + keyAlias signingProp.get("twidere.debug.keyAlias") + keyPassword signingProp.get("twidere.debug.keyPassword") + } + } + release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.release.storeFile")) + storePassword signingProp.get("twidere.release.storePassword") + keyAlias signingProp.get("twidere.release.keyAlias") + keyPassword signingProp.get("twidere.release.keyPassword") + } + } + } + buildTypes { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.debug + } + } + release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.release + } + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile project(':twidere.nyan') + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.google.android.support:wearable:1.1.0' +} diff --git a/twidere.donate.nyanwp.wear/proguard-rules.pro b/twidere.donate.nyanwp.wear/proguard-rules.pro new file mode 100644 index 000000000..ee5b46f04 --- /dev/null +++ b/twidere.donate.nyanwp.wear/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/mariotaku/Tools/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/twidere.donate.nyanwp.wear/src/main/AndroidManifest.xml b/twidere.donate.nyanwp.wear/src/main/AndroidManifest.xml new file mode 100644 index 000000000..dde69e977 --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/AndroidManifest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + diff --git a/twidere.donate.nyanwp.wear/src/main/java/org/mariotaku/twidere/donate/nyanwp/NyanActivity.java b/twidere.donate.nyanwp.wear/src/main/java/org/mariotaku/twidere/donate/nyanwp/NyanActivity.java new file mode 100644 index 000000000..55d39318f --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/java/org/mariotaku/twidere/donate/nyanwp/NyanActivity.java @@ -0,0 +1,44 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.donate.nyanwp; + +import android.app.Activity; +import android.os.Bundle; +import android.support.wearable.view.WatchViewStub; +import android.support.wearable.view.WatchViewStub.OnLayoutInflatedListener; + +import org.mariotaku.twidere.nyan.NyanDaydreamView; + +public class NyanActivity extends Activity implements OnLayoutInflatedListener { + + @Override + public void onLayoutInflated(WatchViewStub watchViewStub) { + final NyanDaydreamView nyanView = (NyanDaydreamView) watchViewStub.findViewById(R.id.nyan_view); + nyanView.setScale(getResources().getInteger(R.integer.default_live_wallpaper_scale)); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_nyan); + final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); + stub.setOnLayoutInflatedListener(this); + } +} diff --git a/twidere.donate.nyanwp.wear/src/main/res/drawable-hdpi/ic_launcher.png b/twidere.donate.nyanwp.wear/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100755 index 000000000..09b2de4b2 Binary files /dev/null and b/twidere.donate.nyanwp.wear/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp.wear/src/main/res/drawable-mdpi/ic_launcher.png b/twidere.donate.nyanwp.wear/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100755 index 000000000..29d52d1b8 Binary files /dev/null and b/twidere.donate.nyanwp.wear/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp.wear/src/main/res/drawable-xhdpi/ic_launcher.png b/twidere.donate.nyanwp.wear/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100755 index 000000000..2cd6045e3 Binary files /dev/null and b/twidere.donate.nyanwp.wear/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp.wear/src/main/res/drawable-xxhdpi/ic_launcher.png b/twidere.donate.nyanwp.wear/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100755 index 000000000..7079aa91d Binary files /dev/null and b/twidere.donate.nyanwp.wear/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp.wear/src/main/res/drawable-xxxhdpi/ic_launcher.png b/twidere.donate.nyanwp.wear/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100755 index 000000000..b4d69c78a Binary files /dev/null and b/twidere.donate.nyanwp.wear/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp.wear/src/main/res/layout/activity_nyan.xml b/twidere.donate.nyanwp.wear/src/main/res/layout/activity_nyan.xml new file mode 100644 index 000000000..1c23a9281 --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/res/layout/activity_nyan.xml @@ -0,0 +1,32 @@ + + + + + diff --git a/twidere.donate.nyanwp.wear/src/main/res/layout/rect_activity_nyan.xml b/twidere.donate.nyanwp.wear/src/main/res/layout/rect_activity_nyan.xml new file mode 100644 index 000000000..571a5cccf --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/res/layout/rect_activity_nyan.xml @@ -0,0 +1,29 @@ + + + + \ No newline at end of file diff --git a/twidere.donate.nyanwp.wear/src/main/res/layout/round_activity_nyan.xml b/twidere.donate.nyanwp.wear/src/main/res/layout/round_activity_nyan.xml new file mode 100644 index 000000000..78cc70d0e --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/res/layout/round_activity_nyan.xml @@ -0,0 +1,28 @@ + + + + \ No newline at end of file diff --git a/twidere.donate.nyanwp.wear/src/main/res/values/strings.xml b/twidere.donate.nyanwp.wear/src/main/res/values/strings.xml new file mode 100644 index 000000000..90708bd82 --- /dev/null +++ b/twidere.donate.nyanwp.wear/src/main/res/values/strings.xml @@ -0,0 +1,27 @@ + + + + + + twidere.donate.nyanwp.wear + Hello Round World! + Hello Square World! + + diff --git a/twidere.donate.nyanwp.wear/web_hi_res_512.png b/twidere.donate.nyanwp.wear/web_hi_res_512.png new file mode 100755 index 000000000..ccc62926c Binary files /dev/null and b/twidere.donate.nyanwp.wear/web_hi_res_512.png differ diff --git a/twidere.donate.nyanwp/.gitignore b/twidere.donate.nyanwp/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/twidere.donate.nyanwp/.gitignore @@ -0,0 +1 @@ +/build diff --git a/twidere.donate.nyanwp/build.gradle b/twidere.donate.nyanwp/build.gradle new file mode 100644 index 000000000..e2f3df84f --- /dev/null +++ b/twidere.donate.nyanwp/build.gradle @@ -0,0 +1,79 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.mariotaku.twidere.donate.nyanwp" + minSdkVersion 14 + targetSdkVersion 21 + versionCode 3 + versionName "1.2" + } + signingConfigs { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.debug.storeFile")) + storePassword signingProp.get("twidere.debug.storePassword") + keyAlias signingProp.get("twidere.debug.keyAlias") + keyPassword signingProp.get("twidere.debug.keyPassword") + } + } + release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.release.storeFile")) + storePassword signingProp.get("twidere.release.storePassword") + keyAlias signingProp.get("twidere.release.keyAlias") + keyPassword signingProp.get("twidere.release.keyPassword") + } + } + } + buildTypes { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.debug + } + } + release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.release + } + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + wearApp project(':twidere.donate.nyanwp.wear') + compile project(':twidere.nyan') + compile fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/twidere.donate.nyanwp/ic_launcher-web.png b/twidere.donate.nyanwp/ic_launcher-web.png new file mode 100644 index 000000000..a9b0a840f Binary files /dev/null and b/twidere.donate.nyanwp/ic_launcher-web.png differ diff --git a/twidere.donate.nyanwp/proguard-rules.pro b/twidere.donate.nyanwp/proguard-rules.pro new file mode 100644 index 000000000..ee5b46f04 --- /dev/null +++ b/twidere.donate.nyanwp/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/mariotaku/Tools/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/twidere.donate.nyanwp/src/androidTest/java/org/mariotaku/twidere/donate/nyanwp/ApplicationTest.java b/twidere.donate.nyanwp/src/androidTest/java/org/mariotaku/twidere/donate/nyanwp/ApplicationTest.java new file mode 100644 index 000000000..b56626471 --- /dev/null +++ b/twidere.donate.nyanwp/src/androidTest/java/org/mariotaku/twidere/donate/nyanwp/ApplicationTest.java @@ -0,0 +1,32 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.donate.nyanwp; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/AndroidManifest.xml b/twidere.donate.nyanwp/src/main/AndroidManifest.xml new file mode 100644 index 000000000..43d37a567 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/drawable-hdpi/ic_launcher.png b/twidere.donate.nyanwp/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 000000000..96a442e5b Binary files /dev/null and b/twidere.donate.nyanwp/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp/src/main/res/drawable-mdpi/ic_launcher.png b/twidere.donate.nyanwp/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 000000000..359047dfa Binary files /dev/null and b/twidere.donate.nyanwp/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp/src/main/res/drawable-nodpi/nyan_sakamoto_thumbnail_bitmap.png b/twidere.donate.nyanwp/src/main/res/drawable-nodpi/nyan_sakamoto_thumbnail_bitmap.png new file mode 100644 index 000000000..37dae3fe4 Binary files /dev/null and b/twidere.donate.nyanwp/src/main/res/drawable-nodpi/nyan_sakamoto_thumbnail_bitmap.png differ diff --git a/twidere.donate.nyanwp/src/main/res/drawable-xhdpi/ic_launcher.png b/twidere.donate.nyanwp/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 000000000..71c6d760f Binary files /dev/null and b/twidere.donate.nyanwp/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp/src/main/res/drawable-xxhdpi/ic_launcher.png b/twidere.donate.nyanwp/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..4df189464 Binary files /dev/null and b/twidere.donate.nyanwp/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/twidere.donate.nyanwp/src/main/res/drawable/nyan_sakamoto_thumbnail.xml b/twidere.donate.nyanwp/src/main/res/drawable/nyan_sakamoto_thumbnail.xml new file mode 100644 index 000000000..0b89d80a6 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/drawable/nyan_sakamoto_thumbnail.xml @@ -0,0 +1,6 @@ + + diff --git a/twidere.donate.nyanwp/src/main/res/values-land/integers.xml b/twidere.donate.nyanwp/src/main/res/values-land/integers.xml new file mode 100644 index 000000000..36fa42641 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values-land/integers.xml @@ -0,0 +1,6 @@ + + + 5 + 17 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values-large-land/integers.xml b/twidere.donate.nyanwp/src/main/res/values-large-land/integers.xml new file mode 100644 index 000000000..ae7d093b6 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values-large-land/integers.xml @@ -0,0 +1,6 @@ + + + 8 + 23 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values-large/integers.xml b/twidere.donate.nyanwp/src/main/res/values-large/integers.xml new file mode 100644 index 000000000..2f9e84b85 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values-large/integers.xml @@ -0,0 +1,7 @@ + + + 10 + 13 + 2 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values-xlarge-land/integers.xml b/twidere.donate.nyanwp/src/main/res/values-xlarge-land/integers.xml new file mode 100644 index 000000000..3dd392f11 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values-xlarge-land/integers.xml @@ -0,0 +1,6 @@ + + + 13 + 31 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values-xlarge/integers.xml b/twidere.donate.nyanwp/src/main/res/values-xlarge/integers.xml new file mode 100644 index 000000000..f30cdcfdc --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values-xlarge/integers.xml @@ -0,0 +1,7 @@ + + + 15 + 19 + 3 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values/colors.xml b/twidere.donate.nyanwp/src/main/res/values/colors.xml new file mode 100644 index 000000000..ce34fda39 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values/colors.xml @@ -0,0 +1,5 @@ + + + #003366 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values/integers.xml b/twidere.donate.nyanwp/src/main/res/values/integers.xml new file mode 100644 index 000000000..2d89b6636 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values/integers.xml @@ -0,0 +1,7 @@ + + + 8 + 11 + 1 + + \ No newline at end of file diff --git a/twidere.donate.nyanwp/src/main/res/values/strings.xml b/twidere.donate.nyanwp/src/main/res/values/strings.xml new file mode 100644 index 000000000..2075de25b --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Twidere Donate Live Wallpaper + Twidere Donate Wallpaper + Twidere Donate Daydream + + diff --git a/twidere.donate.nyanwp/src/main/res/values/styles.xml b/twidere.donate.nyanwp/src/main/res/values/styles.xml new file mode 100644 index 000000000..d98a53a8a --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/values/styles.xml @@ -0,0 +1,21 @@ + + + + diff --git a/twidere.donate.nyanwp/src/main/res/xml/nyan_wallpaper.xml b/twidere.donate.nyanwp/src/main/res/xml/nyan_wallpaper.xml new file mode 100644 index 000000000..58df3aab3 --- /dev/null +++ b/twidere.donate.nyanwp/src/main/res/xml/nyan_wallpaper.xml @@ -0,0 +1,3 @@ + + diff --git a/twidere.nyan/.gitignore b/twidere.nyan/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/twidere.nyan/.gitignore @@ -0,0 +1 @@ +/build diff --git a/twidere.nyan/build.gradle b/twidere.nyan/build.gradle new file mode 100644 index 000000000..c0806b0a6 --- /dev/null +++ b/twidere.nyan/build.gradle @@ -0,0 +1,42 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + minSdkVersion 14 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/twidere.nyan/proguard-rules.pro b/twidere.nyan/proguard-rules.pro new file mode 100644 index 000000000..ee5b46f04 --- /dev/null +++ b/twidere.nyan/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/mariotaku/Tools/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/twidere.nyan/src/androidTest/java/org/mariotaku/twidere/nyan/ApplicationTest.java b/twidere.nyan/src/androidTest/java/org/mariotaku/twidere/nyan/ApplicationTest.java new file mode 100644 index 000000000..4aa0ea779 --- /dev/null +++ b/twidere.nyan/src/androidTest/java/org/mariotaku/twidere/nyan/ApplicationTest.java @@ -0,0 +1,32 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/twidere.nyan/src/main/AndroidManifest.xml b/twidere.nyan/src/main/AndroidManifest.xml new file mode 100644 index 000000000..744fe74da --- /dev/null +++ b/twidere.nyan/src/main/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanConstants.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanConstants.java new file mode 100644 index 000000000..ac8930969 --- /dev/null +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanConstants.java @@ -0,0 +1,30 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +/** + * Created by mariotaku on 14/12/19. + */ +public interface NyanConstants { + + public static final String SHARED_PREFERENCES_NAME = "nyan_preferences"; + + public static final String KEY_LIVE_WALLPAPER_SCALE = "live_wallpaper_scale"; +} diff --git a/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamService.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamService.java new file mode 100644 index 000000000..c9c9b1c1d --- /dev/null +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamService.java @@ -0,0 +1,83 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +import android.annotation.TargetApi; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Resources; +import android.os.Build; +import android.service.dreams.DreamService; +import android.view.View; +import android.view.View.OnSystemUiVisibilityChangeListener; + +@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) +public class NyanDaydreamService extends DreamService implements NyanConstants, + OnSharedPreferenceChangeListener, OnSystemUiVisibilityChangeListener { + + private NyanDaydreamView mNyanDaydreamView; + private SharedPreferences mPreferences; + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + setContentView(R.layout.nyan_daydream); + mNyanDaydreamView.setOnSystemUiVisibilityChangeListener(this); + updateView(); + } + + @Override + public void onContentChanged() { + super.onContentChanged(); + mNyanDaydreamView = (NyanDaydreamView) findViewById(R.id.nyan); + } + + @Override + public void onCreate() { + super.onCreate(); + mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE); + mPreferences.registerOnSharedPreferenceChangeListener(this); + setInteractive(false); + setFullscreen(true); + setScreenBright(false); + } + + @Override + public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { + if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) { + updateView(); + } + } + + @Override + public void onSystemUiVisibilityChange(final int visibility) { + if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { + finish(); + } + } + + private void updateView() { + if (mPreferences == null) return; + final Resources res = getResources(); + final int def = res.getInteger(R.integer.default_live_wallpaper_scale); + mNyanDaydreamView.setScale(mPreferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def)); + } + +} diff --git a/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamView.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamView.java new file mode 100644 index 000000000..bd38bbc5e --- /dev/null +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDaydreamView.java @@ -0,0 +1,116 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.View; + +public class NyanDaydreamView extends View { + + private final InvalidateRunnable mInvalidateRunnable; + + private final NyanDrawingHelper mNyanDrawingHelper; + + public NyanDaydreamView(final Context context) { + this(context, null); + } + + public NyanDaydreamView(final Context context, final AttributeSet attrs) { + this(context, attrs, 0); + } + + public NyanDaydreamView(final Context context, final AttributeSet attrs, final int defStyleAttr) { + super(context, attrs, defStyleAttr); + setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + mNyanDrawingHelper = new DreamViewNyanDrawingHelper(this); + mInvalidateRunnable = new InvalidateRunnable(this); + } + + public void setScale(final float scale) { + mNyanDrawingHelper.setScale(scale); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + post(mInvalidateRunnable); + } + + @Override + protected void onDetachedFromWindow() { + removeCallbacks(mInvalidateRunnable); + super.onDetachedFromWindow(); + } + + @Override + protected void onDraw(final Canvas canvas) { + super.onDraw(canvas); + mNyanDrawingHelper.dispatchDraw(canvas); + } + + @Override + protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + mNyanDrawingHelper.dispatchSizeChanged(w, h); + } + + private static final class DreamViewNyanDrawingHelper extends NyanDrawingHelper { + + private final int mDisplayHeight; + private final NyanDaydreamView mView; + + public DreamViewNyanDrawingHelper(final NyanDaydreamView view) { + super(view.getContext()); + mView = view; + final Resources res = getResources(); + final DisplayMetrics dm = res.getDisplayMetrics(); + mDisplayHeight = dm.heightPixels; + } + + @Override + protected int getRainbowYOffset() { + final int visibility = mView.getSystemUiVisibility(); + if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0) return 0; + return mDisplayHeight - getHeight(); + } + + } + + private static final class InvalidateRunnable implements Runnable { + + private final View mView; + + InvalidateRunnable(final View view) { + mView = view; + } + + @Override + public void run() { + mView.invalidate(); + mView.postDelayed(this, 66); + } + + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/NyanDrawingHelper.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java similarity index 96% rename from twidere/src/main/java/org/mariotaku/twidere/util/NyanDrawingHelper.java rename to twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java index 07fc87c9a..3339c71b9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/NyanDrawingHelper.java +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanDrawingHelper.java @@ -1,23 +1,23 @@ /* - * Twidere - Twitter client for Android - * + * Twidere - Twitter client for Android + * * Copyright (C) 2012-2014 Mariotaku Lee - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.mariotaku.twidere.util; +package org.mariotaku.twidere.nyan; import android.content.Context; import android.content.res.Resources; @@ -34,8 +34,6 @@ import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import org.mariotaku.twidere.R; - import java.util.ArrayList; import java.util.Calendar; import java.util.Random; @@ -95,9 +93,9 @@ public class NyanDrawingHelper { public final void dispatchSizeChanged(final int width, final int height) { mWidth = width; mHeight = height; - mStarsHelper.dispatchSizeChanged(width, height); - mRainbowHelper.dispatchSizeChanged(width, height); - mSakamotoHelper.dispatchSizeChanged(width, height); + for (final IDrawingHelper h : mDrawingHelpers) { + h.dispatchSizeChanged(width, height); + } setupSpirtes(); } @@ -159,7 +157,9 @@ public class NyanDrawingHelper { } private void setupSpirtes() { - final int centerX = mWidth / 2, centerY = mHeight / 2; + final int width = mWidth, height = mHeight; + if (width == 0 || height == 0) return; + final int centerX = width / 2, centerY = height / 2; final int sakamotoDotScale = Math.round(SAKAMOTO_DOT_SIZE * mDensity * mScale); final int sakamotoW = mSakamotoHelper.getIntrinsicWidth() * sakamotoDotScale; final int sakamotoH = mSakamotoHelper.getIntrinsicHeight() * sakamotoDotScale; @@ -184,6 +184,7 @@ public class NyanDrawingHelper { setDrawable(drawable); } + @Override public void dispatchOnDraw(final Canvas canvas) { if (mDrawable == null) return; @@ -226,6 +227,7 @@ public class NyanDrawingHelper { public void setBounds(final int left, final int top, final int right, final int bottom) { if (mDrawable == null) return; if (mAnimationFrames > 0) { + mDrawable.setBounds(left, top, right, bottom); for (int i = 0; i < mAnimationFrames; i++) { final Drawable frame = ((AnimationDrawable) mDrawable).getFrame(i); frame.setBounds(left, top, right, bottom); @@ -273,12 +275,11 @@ public class NyanDrawingHelper { } final Rect bounds = getBounds(); - final int height = bounds.bottom - bounds.top; // Translate down by the remainder - mMatrix.setTranslate(0, bounds.top); + mMatrix.setTranslate(bounds.left, bounds.top); canvas.save(); canvas.setMatrix(mMatrix); - canvas.drawRect(bounds.left, 0, bounds.right, height, mPaint); + canvas.drawRect(0, 0, bounds.width(), bounds.height(), mPaint); canvas.restore(); } @@ -453,9 +454,6 @@ public class NyanDrawingHelper { } private static interface StarAnimFrames { - /* - * @formatter:off - */ static final byte[][] FRAME1 = { { 0, 0, 0, 0, 0, 0, 0 @@ -595,9 +593,6 @@ public class NyanDrawingHelper { } }; - /* - * @formatter:on - */ } } } diff --git a/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanSurfaceHelper.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanSurfaceHelper.java new file mode 100644 index 000000000..2d1057d5b --- /dev/null +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanSurfaceHelper.java @@ -0,0 +1,126 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +import android.content.Context; +import android.graphics.Canvas; +import android.view.SurfaceHolder; + +public final class NyanSurfaceHelper implements SurfaceHolder.Callback { + + private SurfaceHolder mHolder; + private DrawingThread mThread; + private final NyanDrawingHelper mNyanDrawingHelper; + + public NyanSurfaceHelper(final Context context) { + mNyanDrawingHelper = new NyanDrawingHelper(context); + } + + public SurfaceHolder getHolder() { + return mHolder; + } + + public void setScale(final float scale) { + mNyanDrawingHelper.setScale(scale); + } + + public void setSkipDrawing(final boolean skipDrawing) { + if (mThread != null) { + mThread.setSkipDrawing(skipDrawing); + } + } + + public void start() { + if (mThread != null) return; + mThread = new DrawingThread(this, mNyanDrawingHelper); + mThread.start(); + } + + public void stop() { + if (mThread != null) { + mThread.cancel(); + } + mThread = null; + } + + @Override + public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) { + mNyanDrawingHelper.dispatchSizeChanged(width, height); + } + + @Override + public void surfaceCreated(final SurfaceHolder holder) { + mHolder = holder; + start(); + } + + @Override + public void surfaceDestroyed(final SurfaceHolder holder) { + stop(); + mHolder = null; + } + + private static class DrawingThread extends Thread { + + private final NyanSurfaceHelper mSurfaceHelper; + private final NyanDrawingHelper mDrawingHelper; + private boolean mCancelled; + private boolean mSkipDrawing; + + DrawingThread(final NyanSurfaceHelper surfaceHelper, final NyanDrawingHelper drawingHelper) { + mSurfaceHelper = surfaceHelper; + mDrawingHelper = drawingHelper; + } + + public void cancel() { + mCancelled = true; + } + + @Override + public void run() { + while (!mCancelled) { + final long startTime = System.currentTimeMillis(); + drawFrame(); + final long endTime = System.currentTimeMillis(); + try { + Thread.sleep(Math.max(0, 66 - (endTime - startTime))); + } catch (final InterruptedException ignored) { + + } + } + } + + public void setSkipDrawing(final boolean skipDrawing) { + mSkipDrawing = skipDrawing; + } + + private void drawFrame() { + final SurfaceHolder holder = mSurfaceHelper.getHolder(); + if (mSkipDrawing || holder == null || holder.isCreating()) return; + final Canvas c = holder.lockCanvas(); + if (c == null) return; + if (mDrawingHelper != null) { + mDrawingHelper.dispatchDraw(c); + } + holder.unlockCanvasAndPost(c); + } + + } +} diff --git a/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanWallpaperService.java b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanWallpaperService.java new file mode 100644 index 000000000..5a0c0775f --- /dev/null +++ b/twidere.nyan/src/main/java/org/mariotaku/twidere/nyan/NyanWallpaperService.java @@ -0,0 +1,133 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.nyan; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Resources; +import android.os.PowerManager; +import android.service.wallpaper.WallpaperService; +import android.view.SurfaceHolder; + +public class NyanWallpaperService extends WallpaperService implements NyanConstants { + + @Override + public Engine onCreateEngine() { + return new NyanWallpaperEngine(); + } + + private Context getContext() { + return this; + } + + private final class NyanWallpaperEngine extends Engine implements OnSharedPreferenceChangeListener { + + private SharedPreferences mPreferences; + private final BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent.getAction(); + if (Intent.ACTION_SCREEN_ON.equals(action)) { + if (mHelper == null) return; + mHelper.start(); + } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { + if (mHelper == null) return; + mHelper.stop(); + } + + } + }; + + private NyanSurfaceHelper mHelper; + + @Override + public void onCreate(final SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE); + mPreferences.registerOnSharedPreferenceChangeListener(this); + mHelper = new NyanSurfaceHelper(getContext()); + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + registerReceiver(mScreenReceiver, filter); + } + + @Override + public void onDestroy() { + mPreferences.unregisterOnSharedPreferenceChangeListener(this); + unregisterReceiver(mScreenReceiver); + super.onDestroy(); + } + + @Override + public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { + if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) { + updateSurface(); + } + } + + @Override + public void onSurfaceCreated(final SurfaceHolder holder) { + super.onSurfaceCreated(holder); + holder.addCallback(mHelper); + updateSurface(); + updateHelperState(); + } + + @Override + public void onSurfaceDestroyed(final SurfaceHolder holder) { + mHelper.stop(); + holder.removeCallback(mHelper); + super.onSurfaceDestroyed(holder); + } + + @Override + public void onVisibilityChanged(final boolean visible) { + super.onVisibilityChanged(visible); + if (mHelper != null) { + mHelper.setSkipDrawing(!visible); + } + } + + private void updateHelperState() { + final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); + if (pm.isScreenOn()) { + mHelper.start(); + } else { + mHelper.stop(); + } + } + + private void updateSurface() { + if (mPreferences == null) return; + final Resources res = getResources(); + final int def = res.getInteger(R.integer.default_live_wallpaper_scale); + mHelper.setScale(mPreferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def)); + updateHelperState(); + } + + } + +} diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame00_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame00_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame00_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame00_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame01_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame01_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame01_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame01_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame02_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame02_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame02_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame02_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame03_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame03_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame03_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame03_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame04_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame04_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame04_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame04_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame05_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame05_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame05_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame05_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame06_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame06_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame06_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame06_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame07_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame07_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame07_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame07_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame08_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame08_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame08_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame08_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame09_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame09_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame09_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame09_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame10_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame10_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame10_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame10_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame11_tile.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame11_tile.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_rainbow_frame11_tile.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_rainbow_frame11_tile.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame00.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame00.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame00.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame00.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame01.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame01.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame01.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame01.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame02.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame02.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame02.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame02.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame03.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame03.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame03.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame03.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame04.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame04.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame04.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame04.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame05.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame05.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame05.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame05.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame06.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame06.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame06.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame06.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame07.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame07.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame07.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame07.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame08.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame08.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame08.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame08.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame09.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame09.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame09.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame09.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame10.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame10.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame10.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame10.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame11.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame11.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_frame11.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_frame11.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame00.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame00.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame00.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame00.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame01.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame01.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame01.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame01.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame02.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame02.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame02.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame02.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame03.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame03.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame03.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame03.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame04.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame04.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame04.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame04.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame05.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame05.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame05.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame05.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame06.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame06.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame06.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame06.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame07.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame07.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame07.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame07.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame08.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame08.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame08.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame08.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame09.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame09.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame09.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame09.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame10.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame10.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame10.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame10.png diff --git a/twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame11.png b/twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame11.png similarity index 100% rename from twidere/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame11.png rename to twidere.nyan/src/main/res/drawable-nodpi/nyan_sakamoto_santa_frame11.png diff --git a/twidere.nyan/src/main/res/drawable/nyan_sakamoto.xml b/twidere.nyan/src/main/res/drawable/nyan_sakamoto.xml new file mode 100644 index 000000000..86054ddcf --- /dev/null +++ b/twidere.nyan/src/main/res/drawable/nyan_sakamoto.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/drawable/nyan_sakamoto_santa.xml b/twidere.nyan/src/main/res/drawable/nyan_sakamoto_santa.xml new file mode 100644 index 000000000..e1ab6c0d6 --- /dev/null +++ b/twidere.nyan/src/main/res/drawable/nyan_sakamoto_santa.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/layout/nyan_daydream.xml b/twidere.nyan/src/main/res/layout/nyan_daydream.xml new file mode 100644 index 000000000..b8c240809 --- /dev/null +++ b/twidere.nyan/src/main/res/layout/nyan_daydream.xml @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values-land/integers.xml b/twidere.nyan/src/main/res/values-land/integers.xml new file mode 100644 index 000000000..36fa42641 --- /dev/null +++ b/twidere.nyan/src/main/res/values-land/integers.xml @@ -0,0 +1,6 @@ + + + 5 + 17 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values-large-land/integers.xml b/twidere.nyan/src/main/res/values-large-land/integers.xml new file mode 100644 index 000000000..ae7d093b6 --- /dev/null +++ b/twidere.nyan/src/main/res/values-large-land/integers.xml @@ -0,0 +1,6 @@ + + + 8 + 23 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values-large/integers.xml b/twidere.nyan/src/main/res/values-large/integers.xml new file mode 100644 index 000000000..2f9e84b85 --- /dev/null +++ b/twidere.nyan/src/main/res/values-large/integers.xml @@ -0,0 +1,7 @@ + + + 10 + 13 + 2 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values-xlarge-land/integers.xml b/twidere.nyan/src/main/res/values-xlarge-land/integers.xml new file mode 100644 index 000000000..3dd392f11 --- /dev/null +++ b/twidere.nyan/src/main/res/values-xlarge-land/integers.xml @@ -0,0 +1,6 @@ + + + 13 + 31 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values-xlarge/integers.xml b/twidere.nyan/src/main/res/values-xlarge/integers.xml new file mode 100644 index 000000000..f30cdcfdc --- /dev/null +++ b/twidere.nyan/src/main/res/values-xlarge/integers.xml @@ -0,0 +1,7 @@ + + + 15 + 19 + 3 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values/colors.xml b/twidere.nyan/src/main/res/values/colors.xml new file mode 100644 index 000000000..ce34fda39 --- /dev/null +++ b/twidere.nyan/src/main/res/values/colors.xml @@ -0,0 +1,5 @@ + + + #003366 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values/integers.xml b/twidere.nyan/src/main/res/values/integers.xml new file mode 100644 index 000000000..2d89b6636 --- /dev/null +++ b/twidere.nyan/src/main/res/values/integers.xml @@ -0,0 +1,7 @@ + + + 8 + 11 + 1 + + \ No newline at end of file diff --git a/twidere.nyan/src/main/res/values/strings.xml b/twidere.nyan/src/main/res/values/strings.xml new file mode 100644 index 000000000..2075de25b --- /dev/null +++ b/twidere.nyan/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Twidere Donate Live Wallpaper + Twidere Donate Wallpaper + Twidere Donate Daydream + + diff --git a/twidere.wear/build.gradle b/twidere.wear/build.gradle index 37e5c2563..a1aac29b1 100644 --- a/twidere.wear/build.gradle +++ b/twidere.wear/build.gradle @@ -17,8 +17,42 @@ android { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } - buildTypes { + signingConfigs { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.debug.storeFile")) + storePassword signingProp.get("twidere.debug.storePassword") + keyAlias signingProp.get("twidere.debug.keyAlias") + keyPassword signingProp.get("twidere.debug.keyPassword") + } + } release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + Properties signingProp = new Properties() + signingProp.load(signingPropFile.newDataInputStream()) + storeFile file(signingProp.get("twidere.release.storeFile")) + storePassword signingProp.get("twidere.release.storePassword") + keyAlias signingProp.get("twidere.release.keyAlias") + keyPassword signingProp.get("twidere.release.keyPassword") + } + } + } + buildTypes { + debug { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.debug + } + } + release { + File signingPropFile = project.rootProject.file('signing.properties') + if (signingPropFile.exists()) { + signingConfig signingConfigs.release + } minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } diff --git a/twidere/build.gradle b/twidere/build.gradle index c30cfac09..ca53c1ae3 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -16,6 +16,16 @@ android { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/LICENSE' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/notice.txt' + exclude 'META-INF/ASL2.0' + } signingConfigs { debug { File signingPropFile = project.rootProject.file('signing.properties') @@ -40,16 +50,6 @@ android { } } } - packagingOptions { - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/LICENSE' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/license.txt' - exclude 'META-INF/NOTICE' - exclude 'META-INF/NOTICE.txt' - exclude 'META-INF/notice.txt' - exclude 'META-INF/ASL2.0' - } buildTypes { debug { File signingPropFile = project.rootProject.file('signing.properties') @@ -99,7 +99,7 @@ dependencies { compile project(':SlidingMenu') compile project(':DragSortListView') compile project(':MenuComponent') - compile project(':RefreshNow') compile project(':MessageBubbleView') + compile project(':twidere.nyan') compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere/src/fdroid/AndroidManifest.xml b/twidere/src/fdroid/AndroidManifest.xml index 3c79f6944..1a3e32559 100644 --- a/twidere/src/fdroid/AndroidManifest.xml +++ b/twidere/src/fdroid/AndroidManifest.xml @@ -1,4 +1,23 @@ + + diff --git a/twidere/src/fdroid/res/layout/activity_osm_viewer.xml b/twidere/src/fdroid/res/layout/activity_osm_viewer.xml index f2d047f6d..8785bd06c 100644 --- a/twidere/src/fdroid/res/layout/activity_osm_viewer.xml +++ b/twidere/src/fdroid/res/layout/activity_osm_viewer.xml @@ -1,4 +1,23 @@ + + diff --git a/twidere/src/fdroid/res/menu/menu_osm_viewer.xml b/twidere/src/fdroid/res/menu/menu_osm_viewer.xml index 512e86301..3273d4861 100644 --- a/twidere/src/fdroid/res/menu/menu_osm_viewer.xml +++ b/twidere/src/fdroid/res/menu/menu_osm_viewer.xml @@ -1,4 +1,23 @@ + + + + %s", column1.getSQL(), column2.getSQL())); } - public static Expression like(final Column l, final String r) { - return new Expression(String.format(Locale.US, "%s LIKE '%s'", l.getSQL(), r)); + public static Expression likeRaw(final Column column, final String pattern, final String escape) { + return new Expression(String.format(Locale.US, "%s LIKE %s ESCAPE '%s'", column.getSQL(), pattern, escape)); + } + + + public static Expression likeRaw(final Column column, final String pattern) { + return new Expression(String.format(Locale.US, "%s LIKE %s", column.getSQL(), pattern)); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java index caf97aad3..02c40193b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/NyanActivity.java @@ -35,9 +35,9 @@ import android.widget.Toast; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; -import org.mariotaku.twidere.service.NyanDaydreamService; -import org.mariotaku.twidere.service.NyanWallpaperService; -import org.mariotaku.twidere.util.NyanSurfaceHelper; +import org.mariotaku.twidere.nyan.NyanDaydreamService; +import org.mariotaku.twidere.nyan.NyanWallpaperService; +import org.mariotaku.twidere.nyan.NyanSurfaceHelper; public class NyanActivity extends Activity implements Constants, OnLongClickListener, OnSharedPreferenceChangeListener { diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseSupportThemedActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseSupportThemedActivity.java index b998e7734..ddd3bf312 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseSupportThemedActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/BaseSupportThemedActivity.java @@ -19,13 +19,17 @@ package org.mariotaku.twidere.activity.support; +import android.content.Context; import android.content.res.Resources; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.FragmentActivity; import android.support.v4.app.NavUtils; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.view.View; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.activity.iface.IThemedActivity; @@ -105,6 +109,13 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme super.onTitleChanged(title, color); } + @Override + public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) { + final View view = ThemeUtils.createView(name, context, attrs, mCurrentThemeColor); + if (view != null) return view; + return super.onCreateView(name, context, attrs); + } + @Override protected void onResume() { super.onResume(); @@ -114,7 +125,7 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme return true; } - private final void setTheme() { + private void setTheme() { mCurrentThemeResource = getThemeResourceId(); mCurrentThemeColor = getThemeColor(); mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java index b241af5e9..1309a112d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java @@ -78,6 +78,7 @@ import com.nostra13.universalimageloader.utils.IoUtils; import com.twitter.Extractor; import org.mariotaku.dynamicgridview.DraggableArrayAdapter; +import org.mariotaku.menucomponent.internal.menu.MenuUtils; import org.mariotaku.menucomponent.internal.widget.IListPopupWindow; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.BaseArrayAdapter; @@ -106,6 +107,7 @@ import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.TwidereValidator; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.accessor.ViewAccessor; +import org.mariotaku.twidere.util.menu.TwidereMenuInfo; import org.mariotaku.twidere.view.ComposeSelectAccountButton; import org.mariotaku.twidere.view.StatusTextCountView; import org.mariotaku.twidere.view.TwidereMenuBar; @@ -964,12 +966,15 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa final MenuItem itemAttachLocation = menu.findItem(MENU_ADD_LOCATION); if (itemAttachLocation != null) { final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false); + final int menuHighlight = ThemeUtils.getUserAccentColor(this); if (attachLocation && getLocation()) { itemAttachLocation.setChecked(true); + MenuUtils.setMenuInfo(itemAttachLocation, new TwidereMenuInfo(true, menuHighlight)); } else { setProgressVisibility(false); mPreferences.edit().putBoolean(KEY_ATTACH_LOCATION, false).apply(); itemAttachLocation.setChecked(false); + MenuUtils.setMenuInfo(itemAttachLocation, new TwidereMenuInfo(false, menuHighlight)); } } final MenuItem viewItem = menu.findItem(MENU_VIEW); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java index 2626c7041..f0cb6b578 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.util.Pair; +import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; @@ -19,6 +20,8 @@ import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ImageLoadingHandler; +import org.mariotaku.twidere.util.SharedPreferencesWrapper; +import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.view.holder.GapViewHolder; import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; @@ -40,17 +43,21 @@ public abstract class AbsStatusesAdapter extends Adapter implemen private final ImageLoadingHandler mLoadingHandler; private final int mCardLayoutResource; private final AsyncTwitterWrapper mTwitterWrapper; + private final int mCardBackgroundColor; + private final int mTextSize; private boolean mLoadMoreIndicatorEnabled; - private StatusAdapterListener mStatusAdapterListener; public AbsStatusesAdapter(Context context, boolean compact) { mContext = context; final TwidereApplication app = TwidereApplication.getInstance(context); + mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context); mInflater = LayoutInflater.from(context); mImageLoader = app.getImageLoaderWrapper(); mLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress); mTwitterWrapper = app.getTwitterWrapper(); + final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size)); if (compact) { mCardLayoutResource = R.layout.card_item_status_compat; } else { @@ -67,6 +74,11 @@ public abstract class AbsStatusesAdapter extends Adapter implemen return mTwitterWrapper; } + @Override + public float getTextSize() { + return mTextSize; + } + @Override public ImageLoaderWrapper getImageLoader() { return mImageLoader; @@ -114,8 +126,13 @@ public abstract class AbsStatusesAdapter extends Adapter implemen switch (viewType) { case ITEM_VIEW_TYPE_STATUS: { final View view = mInflater.inflate(mCardLayoutResource, parent, false); + final CardView cardView = (CardView) view.findViewById(R.id.card); + if (cardView != null) { + cardView.setCardBackgroundColor(mCardBackgroundColor); + } final StatusViewHolder holder = new StatusViewHolder(this, view); - holder.setupViews(); + holder.setupViewListeners(); + holder.setupViewOptions(); return holder; } case ITEM_VIEW_TYPE_GAP: { diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java index c2f343ad7..e7bf15a62 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java @@ -97,11 +97,6 @@ public class AccountsAdapter extends SimpleDragSortCursorAdapter implements Cons return mImageLoader; } - @Override - public int getLinkHighlightColor() { - return 0; - } - @Override public int getLinkHighlightOption() { return 0; @@ -155,11 +150,6 @@ public class AccountsAdapter extends SimpleDragSortCursorAdapter implements Cons notifyDataSetChanged(); } - @Override - public void setLinkHighlightColor(int color) { - - } - @Override public void setLinkHighlightOption(String option) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseArrayAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseArrayAdapter.java index a5a9a2a7d..7a9b2e0f2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseArrayAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseArrayAdapter.java @@ -38,7 +38,7 @@ public class BaseArrayAdapter extends ArrayAdapter implements IBaseAdapter private final TwidereLinkify mLinkify; private float mTextSize; - private int mLinkHighlightOption, mLinkHighlightColor; + private int mLinkHighlightOption; private boolean mDisplayProfileImage, mNicknameOnly, mDisplayNameFirst, mShowAccountColor; @@ -65,11 +65,6 @@ public class BaseArrayAdapter extends ArrayAdapter implements IBaseAdapter return mImageLoader; } - @Override - public final int getLinkHighlightColor() { - return mLinkHighlightColor; - } - @Override public final int getLinkHighlightOption() { return mLinkHighlightOption; @@ -122,12 +117,6 @@ public class BaseArrayAdapter extends ArrayAdapter implements IBaseAdapter mDisplayProfileImage = display; } - @Override - public final void setLinkHighlightColor(final int color) { - mLinkify.setLinkTextColor(color); - mLinkHighlightColor = color; - } - @Override public final void setLinkHighlightOption(final String option) { final int optionInt = getLinkHighlightOptionInt(option); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseCursorAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseCursorAdapter.java index 8ad13a995..9c2fd89c8 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseCursorAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/BaseCursorAdapter.java @@ -68,12 +68,7 @@ public class BaseCursorAdapter extends SimpleCursorAdapter implements IBaseAdapt return mImageLoader; } - @Override - public final int getLinkHighlightColor() { - return mLinkHighlightColor; - } - - @Override + @Override public final int getLinkHighlightOption() { return mLinkHighlightOption; } @@ -126,15 +121,7 @@ public class BaseCursorAdapter extends SimpleCursorAdapter implements IBaseAdapt notifyDataSetChanged(); } - @Override - public final void setLinkHighlightColor(final int color) { - if (color == mLinkHighlightColor) return; - mLinkHighlightColor = color; - mLinkify.setLinkTextColor(color); - notifyDataSetChanged(); - } - - @Override + @Override public final void setLinkHighlightOption(final String option) { final int option_int = getLinkHighlightOptionInt(option); if (option_int == mLinkHighlightOption) return; diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableActivitiesAboutMeAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableActivitiesAboutMeAdapter.java index 25cf2824c..fee041d54 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableActivitiesAboutMeAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableActivitiesAboutMeAdapter.java @@ -252,14 +252,6 @@ public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivities holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : context .getString(R.string.name_with_nickname, status.user_name, nick)); holder.screen_name.setText("@" + status.user_screen_name); - if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) { - linkify.applyUserProfileLinkNoHighlight(holder.name, status.account_id, status.user_id, - status.user_screen_name); - linkify.applyUserProfileLinkNoHighlight(holder.screen_name, status.account_id, status.user_id, - status.user_screen_name); - holder.name.setMovementMethod(null); - holder.screen_name.setMovementMethod(null); - } holder.time.setTime(status.timestamp); holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite, ParcelableLocation.isValidLocation(status.location), hasMedia, status.is_possibly_sensitive); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/UserHashtagAutoCompleteAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/UserHashtagAutoCompleteAdapter.java index c1df67277..ac2e73f23 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/UserHashtagAutoCompleteAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/UserHashtagAutoCompleteAdapter.java @@ -34,6 +34,7 @@ import android.widget.TextView; import org.mariotaku.querybuilder.Columns.Column; import org.mariotaku.querybuilder.Expression; +import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.RawItemArray; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; @@ -41,14 +42,9 @@ import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.provider.TweetStore.CachedHashtags; import org.mariotaku.twidere.provider.TweetStore.CachedUsers; import org.mariotaku.twidere.provider.TweetStore.CachedValues; -import org.mariotaku.twidere.util.ArrayUtils; import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ParseUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Map.Entry; +import org.mariotaku.twidere.util.Utils; import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname; @@ -56,9 +52,6 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen private static final String[] FROM = new String[0]; private static final int[] TO = new int[0]; - private static final String[] CACHED_USERS_COLUMNS = new String[]{CachedUsers._ID, CachedUsers.USER_ID, - CachedUsers.NAME, CachedUsers.SCREEN_NAME, CachedUsers.PROFILE_IMAGE_URL}; - private final Locale mLocale; private final ContentResolver mResolver; private final SQLiteDatabase mDatabase; @@ -87,7 +80,6 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen mDatabase = app != null ? app.getSQLiteDatabase() : null; mDisplayProfileImage = mPreferences != null && mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true); mNicknameOnly = mPreferences != null && mPreferences.getBoolean(KEY_NICKNAME_ONLY, false); - mLocale = context.getResources().getConfiguration().locale; } public UserHashtagAutoCompleteAdapter(final EditText view) { @@ -164,12 +156,21 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen mToken = token; final String constraintEscaped = constraint != null ? constraint.toString().replaceAll("_", "^_") : null; if (isAtSymbol(token)) { - final String selection = constraintEscaped != null ? (CachedUsers.SCREEN_NAME + " LIKE ?||'%' ESCAPE '^'") + " OR " + CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'" + " OR " + Expression.in(new Column(CachedUsers.USER_ID), - new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL() : null; - final String[] selectionArgs = constraintEscaped != null ? new String[]{constraintEscaped, - constraintEscaped} : null; - final String orderBy = CachedUsers.SCREEN_NAME + ", " + CachedUsers.NAME; - return mResolver.query(CachedUsers.CONTENT_URI, CACHED_USERS_COLUMNS, selection, selectionArgs, orderBy); + final Expression selection; + final String[] selectionArgs; + if (constraintEscaped != null) { + final long[] nicknameIds = Utils.getMatchedNicknameIds(ParseUtils.parseString(constraint), mUserNicknamePreferences); + selection = Expression.or(Expression.likeRaw(new Column(CachedUsers.SCREEN_NAME), "?||'%'", "^"), + Expression.likeRaw(new Column(CachedUsers.NAME), "?||'%'", "^"), + Expression.in(new Column(CachedUsers.USER_ID), new RawItemArray(nicknameIds))); + selectionArgs = new String[]{constraintEscaped, constraintEscaped}; + } else { + selection = null; + selectionArgs = null; + } + final OrderBy orderBy = new OrderBy(CachedUsers.SCREEN_NAME, CachedUsers.NAME); + return mResolver.query(CachedUsers.CONTENT_URI, CachedUsers.BASIC_COLUMNS, + selection != null ? selection.getSQL() : null, selectionArgs, orderBy.getSQL()); } else { final String selection = constraintEscaped != null ? CachedHashtags.NAME + " LIKE ?||'%' ESCAPE '^'" : null; @@ -190,21 +191,6 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen return super.swapCursor(cursor); } - private long[] getMatchedNicknameIds(final String str) { - if (TextUtils.isEmpty(str)) return new long[0]; - final List list = new ArrayList(); - for (final Entry entry : mUserNicknamePreferences.getAll().entrySet()) { - final String value = ParseUtils.parseString(entry.getValue()); - final long key = ParseUtils.parseLong(entry.getKey(), -1); - if (key == -1 || TextUtils.isEmpty(value)) { - continue; - } - if (value.toLowerCase(mLocale).startsWith(str.toLowerCase(mLocale))) { - list.add(key); - } - } - return ArrayUtils.fromList(list); - } private static boolean isAtSymbol(final char character) { switch (character) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IBaseAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IBaseAdapter.java index 6dc3af0ef..7988b24da 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IBaseAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IBaseAdapter.java @@ -28,9 +28,7 @@ public interface IBaseAdapter extends Constants, ListAdapter { public ImageLoaderWrapper getImageLoader(); - public int getLinkHighlightColor(); - - public int getLinkHighlightOption(); + public int getLinkHighlightOption(); public float getTextSize(); @@ -48,9 +46,7 @@ public interface IBaseAdapter extends Constants, ListAdapter { public void setDisplayProfileImage(boolean display); - public void setLinkHighlightColor(int color); - - public void setLinkHighlightOption(String option); + public void setLinkHighlightOption(String option); public void setNicknameOnly(boolean nicknameOnly); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java index a9ae87540..6561a4023 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java @@ -30,4 +30,6 @@ public interface IStatusesAdapter extends IGapSupportedAdapter, ICardSuppo void setData(Data data); AsyncTwitterWrapper getTwitterWrapper(); + + float getTextSize(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/iface/IBasePullToRefreshFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/iface/IBasePullToRefreshFragment.java index 5f7f8a68f..fe8698203 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/iface/IBasePullToRefreshFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/iface/IBasePullToRefreshFragment.java @@ -19,13 +19,11 @@ package org.mariotaku.twidere.fragment.iface; -import org.mariotaku.refreshnow.widget.OnRefreshListener; -import org.mariotaku.refreshnow.widget.iface.IRefreshNowView; +public interface IBasePullToRefreshFragment { -public interface IBasePullToRefreshFragment extends IRefreshNowView, OnRefreshListener { + public void onRefresh(); - public void onRefreshFromEnd(); - - public void onRefreshFromStart(); + public boolean isRefreshing(); + void setRefreshing(boolean refresh); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseActivitiesListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseActivitiesListFragment.java index 3b4f02475..269f99095 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseActivitiesListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseActivitiesListFragment.java @@ -79,24 +79,18 @@ public abstract class BaseActivitiesListFragment extends BasePullToRefreshListFr @Override public void onLoadFinished(final Loader> loader, final List data) { setProgressBarIndeterminateVisibility(false); - setRefreshComplete(); mData = data; mAdapter.setData(data); if (loader instanceof Twitter4JActivitiesLoader) { final boolean multipleAccounts = ((Twitter4JActivitiesLoader) loader).getAccountIds().length > 1; mAdapter.setShowAccountColor(multipleAccounts); } - setRefreshComplete(); + setRefreshing(false); setListShown(true); } @Override - public void onRefreshFromEnd() { - - } - - @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; getLoaderManager().restartLoader(0, getArguments(), this); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshListFragment.java index 0e2aba204..870cf18e5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshListFragment.java @@ -20,53 +20,20 @@ package org.mariotaku.twidere.fragment.support; import android.app.Activity; -import android.content.Context; import android.graphics.Rect; -import android.os.Bundle; import android.support.v4.app.FragmentActivity; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.FrameLayout; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; -import org.mariotaku.refreshnow.widget.OnRefreshListener; -import org.mariotaku.refreshnow.widget.RefreshMode; -import org.mariotaku.refreshnow.widget.RefreshNowConfig; -import org.mariotaku.refreshnow.widget.RefreshNowListView; -import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator; import org.mariotaku.twidere.activity.iface.IControlBarActivity; import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener; import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment; -import org.mariotaku.twidere.util.ThemeUtils; - -import static android.support.v4.app.ListFragmentTrojan.INTERNAL_EMPTY_ID; -import static android.support.v4.app.ListFragmentTrojan.INTERNAL_LIST_CONTAINER_ID; -import static android.support.v4.app.ListFragmentTrojan.INTERNAL_PROGRESS_CONTAINER_ID; public abstract class BasePullToRefreshListFragment extends BaseSupportListFragment implements IBasePullToRefreshFragment, ControlBarOffsetListener { - @Override - public RefreshNowListView getListView() { - return (RefreshNowListView) super.getListView(); - } - - @Override - public RefreshMode getRefreshMode() { - if (getView() == null) return RefreshMode.NONE; - return getListView().getRefreshMode(); - } @Override public boolean isRefreshing() { - if (getView() == null) return false; - return getListView().isRefreshing(); + return false; } @Override @@ -86,156 +53,24 @@ public abstract class BasePullToRefreshListFragment extends BaseSupportListFragm } } - /** - * Provide default implementation to return a simple list view. Subclasses - * can override to replace with their own layout. If doing so, the returned - * view hierarchy must have a ListView whose id is - * {@link android.R.id#list android.R.id.list} and can optionally have a - * sibling view id {@link android.R.id#empty android.R.id.empty} that is to - * be shown when the list is empty. - *

- * If you are overriding this method with your own custom content, consider - * including the standard layout {@link android.R.layout#list_content} in - * your layout file, so that you continue to retain all of the standard - * behavior of ListFragment. In particular, this is currently the only way - * to have the built-in indeterminant progress state be shown. - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { - final Context context = getActivity(); - - final FrameLayout root = new FrameLayout(context); - - // ------------------------------------------------------------------ - - final LinearLayout pframe = new LinearLayout(context); - pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID); - pframe.setOrientation(LinearLayout.VERTICAL); - pframe.setVisibility(View.GONE); - pframe.setGravity(Gravity.CENTER); - - final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge); - pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - // ------------------------------------------------------------------ - - final FrameLayout lframe = new FrameLayout(context); - lframe.setId(INTERNAL_LIST_CONTAINER_ID); - - final TextView tv = new TextView(getActivity()); - tv.setId(INTERNAL_EMPTY_ID); - tv.setGravity(Gravity.CENTER); - lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - final RefreshNowListView lv = new RefreshNowListView(getActivity()); - lv.setId(android.R.id.list); - lv.setOverScrollMode(View.OVER_SCROLL_NEVER); - lv.setDrawSelectorOnTop(false); - lv.setOnRefreshListener(this); - lv.setConfig(ThemeUtils.buildRefreshNowConfig(context)); - lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - final RefreshNowProgressIndicator indicator = new RefreshNowProgressIndicator(context); - indicator.setConfig(ThemeUtils.buildRefreshIndicatorConfig(context)); - final int indicatorHeight = Math.round(3 * getResources().getDisplayMetrics().density); - lframe.addView(indicator, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, indicatorHeight, - Gravity.TOP)); - - lv.setRefreshIndicatorView(indicator); - - root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - // ------------------------------------------------------------------ - - root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - return root; - } - - @Override - public void onRefreshComplete() { - - } - - @Override - public final void onRefreshStart(final RefreshMode mode) { - if (mode.hasStart()) { - onRefreshFromStart(); - } else if (mode.hasEnd()) { - onRefreshFromEnd(); - } - } - - @Override - public void setConfig(final RefreshNowConfig config) { - if (getView() == null) return; - getListView().setConfig(config); - } - - @Override - public void setOnRefreshListener(final OnRefreshListener listener) { - - } - - @Override - public void setRefreshComplete() { - if (getView() == null) return; - getListView().setRefreshComplete(); - } - - @Override - public void setRefreshIndicatorView(final View view) { - if (getView() == null) return; - getListView().setRefreshIndicatorView(view); - } - @Override public void setRefreshing(final boolean refresh) { - if (getView() == null) return; - getListView().setRefreshing(refresh); - } - - @Override - public void setRefreshMode(final RefreshMode mode) { - if (getView() == null) return; - getListView().setRefreshMode(mode); } @Override public boolean triggerRefresh() { - onRefreshFromStart(); + onRefresh(); setRefreshing(true); return true; } - public View getRefreshIndicatorView() { - return getListView().getRefreshIndicatorView(); - } - @Override protected void fitSystemWindows(Rect insets) { super.fitSystemWindows(insets); - final View indicator = getRefreshIndicatorView(); - final LayoutParams lp = indicator.getLayoutParams(); - if (lp instanceof MarginLayoutParams) { - ((MarginLayoutParams) lp).topMargin = insets.top; - indicator.setLayoutParams(lp); - } } @Override public void onControlBarOffsetChanged(IControlBarActivity activity, float offset) { - final View indicator = getRefreshIndicatorView(); - if (indicator == null) return; - indicator.setTranslationY(activity.getControlBarHeight() * (offset - 1)); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUserListsListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUserListsListFragment.java index f316903a3..13f6217ea 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUserListsListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUserListsListFragment.java @@ -33,7 +33,6 @@ import android.view.View; import android.widget.AbsListView; import android.widget.ListView; -import org.mariotaku.refreshnow.widget.RefreshMode; import org.mariotaku.twidere.adapter.ParcelableUserListsAdapter; import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener; import org.mariotaku.twidere.loader.support.BaseUserListsLoader; @@ -131,7 +130,6 @@ abstract class BaseUserListsListFragment extends BasePullToRefreshListFragment i setListAdapter(mAdapter); getLoaderManager().initLoader(0, getArguments(), this); setListShown(false); - setRefreshMode(RefreshMode.NONE); } @Override @@ -163,7 +161,7 @@ abstract class BaseUserListsListFragment extends BasePullToRefreshListFragment i mCursor = cursor; } } - setRefreshComplete(); + setRefreshing(false); setListShown(true); } @@ -203,13 +201,7 @@ abstract class BaseUserListsListFragment extends BasePullToRefreshListFragment i } @Override - public void onRefreshFromEnd() { - if (mLoadMoreAutomatically) return; - loadMoreUserLists(); - } - - @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; getLoaderManager().restartLoader(0, getArguments(), this); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUsersListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUsersListFragment.java index f2038a077..e3383e15e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUsersListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseUsersListFragment.java @@ -59,7 +59,6 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple private ParcelableUsersAdapter mAdapter; - private boolean mLoadMoreAutomatically; private ListView mListView; private long mAccountId; @@ -177,7 +176,7 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple setProgressBarIndeterminateVisibility(false); mAdapter.setData(data); mAdapter.setShowAccountColor(shouldShowAccountColor()); - setRefreshComplete(); + setRefreshing(false); setListShown(true); } @@ -209,18 +208,12 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple @Override public void onReachedBottom() { - if (!mLoadMoreAutomatically) return; loadMoreUsers(); } - @Override - public void onRefreshFromEnd() { - if (mLoadMoreAutomatically) return; - loadMoreUsers(); - } @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; getLoaderManager().restartLoader(0, getArguments(), this); } @@ -228,7 +221,6 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple @Override public void onResume() { super.onResume(); - mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false); configBaseCardAdapter(getActivity(), mAdapter); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java index 634ef81b7..e0d257638 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java @@ -34,6 +34,7 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.text.Editable; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -60,6 +61,10 @@ import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import org.mariotaku.menucomponent.widget.PopupMenu; +import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; +import org.mariotaku.querybuilder.OrderBy; +import org.mariotaku.querybuilder.RawItemArray; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.ImagePickerActivity; import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; @@ -69,9 +74,9 @@ import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListe import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.loader.support.UserSearchLoader; import org.mariotaku.twidere.model.ParcelableAccount; -import org.mariotaku.twidere.model.ParcelableAccount.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableUser; +import org.mariotaku.twidere.model.ParcelableUser.CachedIndices; import org.mariotaku.twidere.provider.TweetStore; import org.mariotaku.twidere.provider.TweetStore.CachedUsers; import org.mariotaku.twidere.provider.TweetStore.DirectMessages; @@ -86,6 +91,8 @@ import org.mariotaku.twidere.util.message.TaskStateChangedEvent; import org.mariotaku.twidere.view.StatusTextCountView; import org.mariotaku.twidere.view.iface.IColorLabelView; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; @@ -99,6 +106,8 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl private static final int LOADER_ID_SEARCH_USERS = 1; + private static final String EXTRA_FROM_CACHE = "from_cache"; + private TwidereValidator mValidator; private AsyncTwitterWrapper mTwitterWrapper; private SharedPreferences mPreferences; @@ -128,7 +137,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl private DirectMessagesConversationAdapter mAdapter; private SimpleParcelableUsersAdapter mUsersSearchAdapter; - private ParcelableCredentials mAccount; + private ParcelableAccount mAccount; private ParcelableUser mRecipient; private ImageLoaderWrapper mImageLoader; @@ -141,7 +150,8 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl mUsersSearchProgress.setVisibility(View.VISIBLE); final long accountId = args.getLong(EXTRA_ACCOUNT_ID); final String query = args.getString(EXTRA_QUERY); - return new UserSearchLoader(getActivity(), accountId, query, 0, null); + final boolean fromCache = args.getBoolean(EXTRA_FROM_CACHE); + return new MyUserSearchLoader(getActivity(), accountId, query, fromCache); } @Override @@ -187,12 +197,29 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl mAccountSpinner = (Spinner) actionBarView.findViewById(R.id.account_spinner); mUserQuery = (EditText) actionBarView.findViewById(R.id.user_query); mQueryButton = actionBarView.findViewById(R.id.query_button); - final List accounts = ParcelableCredentials.getCredentialsList(activity, false); + final List accounts = ParcelableAccount.getAccountsList(activity, false); final AccountsSpinnerAdapter accountsSpinnerAdapter = new AccountsSpinnerAdapter(actionBar.getThemedContext(), R.layout.spinner_item_account_icon); accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_user); accountsSpinnerAdapter.addAll(accounts); mAccountSpinner.setAdapter(accountsSpinnerAdapter); mAccountSpinner.setOnItemSelectedListener(this); + mUserQuery.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem(); + searchUsers(account.account_id, ParseUtils.parseString(s), true); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); mQueryButton.setOnClickListener(this); mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); mMessageDrafts = getSharedPreferences(MESSAGE_DRAFTS_PREFERENCES_NAME, Context.MODE_PRIVATE); @@ -213,7 +240,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl mUsersSearchList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - final ParcelableCredentials account = (ParcelableCredentials) mAccountSpinner.getSelectedItem(); + final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem(); showConversation(account, mUsersSearchAdapter.getItem(position)); updateProfileImage(); } @@ -229,14 +256,14 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl mAddImageButton.setOnClickListener(this); mSendButton.setEnabled(false); if (savedInstanceState != null) { - final ParcelableCredentials account = savedInstanceState.getParcelable(EXTRA_ACCOUNT); + final ParcelableAccount account = savedInstanceState.getParcelable(EXTRA_ACCOUNT); final ParcelableUser recipient = savedInstanceState.getParcelable(EXTRA_USER); showConversation(account, recipient); mEditText.setText(savedInstanceState.getString(EXTRA_TEXT)); mImageUri = savedInstanceState.getString(EXTRA_IMAGE_URI); } else { final Bundle args = getArguments(); - final ParcelableCredentials account; + final ParcelableAccount account; final ParcelableUser recipient; if (args != null) { if (args.containsKey(EXTRA_ACCOUNT)) { @@ -247,7 +274,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl final long userId = args.getLong(EXTRA_RECIPIENT_ID, -1); final int accountPos = accountsSpinnerAdapter.findItemPosition(accountId); account = accountPos < 0 ? ParcelableAccount.getCredentials(activity, accountId) - : (ParcelableCredentials) accountsSpinnerAdapter.getItem(accountPos); + : accountsSpinnerAdapter.getItem(accountPos); recipient = Utils.getUserForConversation(activity, accountId, userId); } else { account = null; @@ -260,6 +287,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl } } } + mEditText.setSelection(mEditText.length()); final boolean isValid = mAccount != null && mRecipient != null; mConversationContainer.setVisibility(isValid ? View.VISIBLE : View.GONE); mRecipientSelectorContainer.setVisibility(isValid ? View.GONE : View.VISIBLE); @@ -354,7 +382,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl } case R.id.query_button: { final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem(); - searchUsers(account.account_id, ParseUtils.parseString(mUserQuery.getText())); + searchUsers(account.account_id, ParseUtils.parseString(mUserQuery.getText()), false); break; } } @@ -362,10 +390,11 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl private boolean mSearchUsersLoaderInitialized; - private void searchUsers(long accountId, String query) { + private void searchUsers(long accountId, String query, boolean fromCache) { final Bundle args = new Bundle(); args.putLong(EXTRA_ACCOUNT_ID, accountId); args.putString(EXTRA_QUERY, query); + args.putBoolean(EXTRA_FROM_CACHE, fromCache); final LoaderManager lm = getLoaderManager(); if (mSearchUsersLoaderInitialized) { lm.restartLoader(LOADER_ID_SEARCH_USERS, args, mSearchLoadersCallback); @@ -416,7 +445,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl @Override public void onItemSelected(final AdapterView parent, final View view, final int pos, final long id) { - final ParcelableCredentials account = (ParcelableCredentials) mAccountSpinner.getSelectedItem(); + final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem(); if (account != null) { mAccount = account; updateProfileImage(); @@ -491,7 +520,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl // } // // @Override -// public void onRefreshFromStart() { +// public void onRefresh() { // loadMoreMessages(); // } @@ -536,7 +565,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl mPopupMenu.dismiss(); } - final ParcelableCredentials account = mAccount; + final ParcelableAccount account = mAccount; final ParcelableUser recipient = mRecipient; if (account != null && recipient != null) { final String key = getDraftsTextKey(account.account_id, recipient.id); @@ -577,7 +606,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl // return true; // } - public void showConversation(final ParcelableCredentials account, final ParcelableUser recipient) { + public void showConversation(final ParcelableAccount account, final ParcelableUser recipient) { mAccount = account; mRecipient = recipient; if (account == null || recipient == null) return; @@ -643,7 +672,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl // } private void sendDirectMessage() { - final ParcelableCredentials account = mAccount; + final ParcelableAccount account = mAccount; final ParcelableUser recipient = mRecipient; if (mAccount == null || mRecipient == null) return; final String message = mEditText.getText().toString(); @@ -760,4 +789,50 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl } } + + private static class MyUserSearchLoader extends UserSearchLoader { + private final boolean mFromCache; + + public MyUserSearchLoader(Context context, long accountId, String query, boolean fromCache) { + super(context, accountId, query, 0, null); + mFromCache = fromCache; + } + + @Override + public List loadInBackground() { + final String query = getQuery(); + if (TextUtils.isEmpty(query)) return Collections.emptyList(); + if (mFromCache) { + final Context context = getContext(); + final ArrayList cachedList = new ArrayList<>(); + final String queryEscaped = query.replace("_", "^_"); + final Expression selection; + final String[] selectionArgs; + if (queryEscaped != null) { + final SharedPreferences nicknamePrefs = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE); + final long[] nicknameIds = Utils.getMatchedNicknameIds(ParseUtils.parseString(query), nicknamePrefs); + selection = Expression.or(Expression.likeRaw(new Column(CachedUsers.SCREEN_NAME), "?||'%'", "^"), + Expression.likeRaw(new Column(CachedUsers.NAME), "?||'%'", "^"), + Expression.in(new Column(CachedUsers.USER_ID), new RawItemArray(nicknameIds))); + selectionArgs = new String[]{queryEscaped, queryEscaped}; + } else { + selection = null; + selectionArgs = null; + } + final OrderBy orderBy = new OrderBy(CachedUsers.SCREEN_NAME, CachedUsers.NAME); + final Cursor c = context.getContentResolver().query(CachedUsers.CONTENT_URI, + CachedUsers.BASIC_COLUMNS, selection != null ? selection.getSQL() : null, + selectionArgs, orderBy.getSQL()); + final CachedIndices i = new CachedIndices(c); + c.moveToFirst(); + while (!c.isAfterLast()) { + cachedList.add(new ParcelableUser(c, i, -1)); + c.moveToNext(); + } + c.close(); + return cachedList; + } + return super.loadInBackground(); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java index 5a9a68cd4..99ab26d35 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java @@ -72,8 +72,6 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem private SharedPreferences mPreferences; private ListView mListView; - private boolean mLoadMoreAutomatically; - private DirectMessageEntriesAdapter mAdapter; private int mFirstVisibleItem; @@ -158,13 +156,7 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem } @Override - public void onRefreshFromEnd() { - if (mLoadMoreAutomatically) return; - loadMoreMessages(); - } - - @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; new TwidereAsyncTask() { @@ -192,7 +184,6 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem super.onResume(); mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false)); configBaseCardAdapter(getActivity(), mAdapter); - mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false); } @Override @@ -276,7 +267,6 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem @Override protected void onReachedBottom() { - if (!mLoadMoreAutomatically) return; loadMoreMessages(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SavedSearchesListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SavedSearchesListFragment.java index 17661c588..120622f0b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SavedSearchesListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SavedSearchesListFragment.java @@ -103,16 +103,11 @@ public class SavedSearchesListFragment extends BasePullToRefreshListFragment imp } mAdapter.setData(data); setListShown(true); - setRefreshComplete(); + setRefreshing(false); } @Override - public void onRefreshFromEnd() { - - } - - @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; getLoaderManager().restartLoader(0, null, this); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java index ced03f645..e9720f7bd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java @@ -34,6 +34,7 @@ import android.view.View; import android.view.ViewGroup; import org.mariotaku.twidere.R; +import org.mariotaku.twidere.activity.iface.IThemedActivity; import org.mariotaku.twidere.activity.support.LinkHandlerActivity; import org.mariotaku.twidere.adapter.support.SupportTabsAdapter; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; @@ -83,6 +84,11 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll mViewPager.setAdapter(mAdapter); mViewPager.setOffscreenPageLimit(2); mPagerIndicator.setViewPager(mViewPager); + if (activity instanceof IThemedActivity) { + mPagerIndicator.setStripColor(((IThemedActivity) activity).getCurrentThemeColor()); + } else { + + } if (savedInstanceState == null && args != null && args.containsKey(EXTRA_QUERY)) { final String query = args.getString(EXTRA_QUERY); final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(), diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java index 39effa80f..6137260dd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java @@ -83,7 +83,7 @@ import org.mariotaku.twidere.util.OnLinkClickHandler; import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.view.ProfileImageView; +import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.StatusTextView; import org.mariotaku.twidere.view.TwidereMenuBar; import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; @@ -346,6 +346,7 @@ public class StatusFragment extends BaseSupportFragment private final boolean mNameFirst, mNicknameOnly; private final int mCardLayoutResource; private final int mTextSize; + private final int mCardBackgroundColor; private ParcelableStatus mStatus; private ParcelableCredentials mStatusAccount; @@ -362,6 +363,7 @@ public class StatusFragment extends BaseSupportFragment mInflater = LayoutInflater.from(context); mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper(); mImageLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress); + mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context); mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true); mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, true); mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size)); @@ -419,7 +421,7 @@ public class StatusFragment extends BaseSupportFragment return getConversationCount() + 1 + getRepliesCount() + 1; } - public int getTextSize() { + public float getTextSize() { return mTextSize; } @@ -491,12 +493,20 @@ public class StatusFragment extends BaseSupportFragment switch (viewType) { case VIEW_TYPE_DETAIL_STATUS: { final View view = mInflater.inflate(R.layout.header_status, parent, false); + final CardView cardView = (CardView) view.findViewById(R.id.card); + if (cardView != null) { + cardView.setCardBackgroundColor(mCardBackgroundColor); + } return new DetailStatusViewHolder(this, view); } case VIEW_TYPE_LIST_STATUS: { final View view = mInflater.inflate(mCardLayoutResource, parent, false); + final CardView cardView = (CardView) view.findViewById(R.id.card); + if (cardView != null) { + cardView.setCardBackgroundColor(mCardBackgroundColor); + } final StatusViewHolder holder = new StatusViewHolder(this, view); - holder.setupViews(); + holder.setupViewListeners(); return holder; } case VIEW_TYPE_CONVERSATION_LOAD_INDICATOR: @@ -657,7 +667,7 @@ public class StatusFragment extends BaseSupportFragment private final TwidereMenuBar menuBar; private final TextView nameView, screenNameView; private final StatusTextView textView; - private final ProfileImageView profileImageView; + private final ShapedImageView profileImageView; private final ImageView profileTypeView; private final TextView timeSourceView; private final TextView replyRetweetStatusView; @@ -679,7 +689,7 @@ public class StatusFragment extends BaseSupportFragment nameView = (TextView) itemView.findViewById(R.id.name); screenNameView = (TextView) itemView.findViewById(R.id.screen_name); textView = (StatusTextView) itemView.findViewById(R.id.text); - profileImageView = (ProfileImageView) itemView.findViewById(R.id.profile_image); + profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image); profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type); timeSourceView = (TextView) itemView.findViewById(R.id.time_source); replyRetweetStatusView = (TextView) itemView.findViewById(R.id.reply_retweet_status); @@ -847,7 +857,6 @@ public class StatusFragment extends BaseSupportFragment textView.setText(Html.fromHtml(status.text_html)); final TwidereLinkify linkify = new TwidereLinkify(new OnLinkClickHandler(context, null)); - linkify.setLinkTextColor(ThemeUtils.getUserLinkTextColor(context)); linkify.applyAllLinks(textView, status.account_id, status.is_possibly_sensitive); ThemeUtils.applyParagraphSpacing(textView, 1.1f); @@ -913,7 +922,7 @@ public class StatusFragment extends BaseSupportFragment mediaPreviewLoad.setOnClickListener(this); profileContainer.setOnClickListener(this); - final int defaultTextSize = adapter.getTextSize(); + final float defaultTextSize = adapter.getTextSize(); nameView.setTextSize(defaultTextSize * 1.25f); textView.setTextSize(defaultTextSize * 1.25f); screenNameView.setTextSize(defaultTextSize * 0.85f); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggectionsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggectionsFragment.java index 7307398df..06f5aa0c9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggectionsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/TrendsSuggectionsFragment.java @@ -92,12 +92,7 @@ public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment imp } @Override - public void onRefreshFromEnd() { - - } - - @Override - public void onRefreshFromStart() { + public void onRefresh() { if (isRefreshing()) return; final AsyncTwitterWrapper twitter = getTwitterWrapper(); if (twitter == null) return; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java index de3dbac30..105cb0b69 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java @@ -36,6 +36,7 @@ import android.graphics.ColorFilter; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PixelFormat; +import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -62,7 +63,6 @@ import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; @@ -91,6 +91,7 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCal import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; import org.mariotaku.twidere.graphic.ActionBarColorDrawable; import org.mariotaku.twidere.loader.support.ParcelableUserLoader; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUserList; import org.mariotaku.twidere.model.SingleResponse; @@ -105,6 +106,7 @@ import org.mariotaku.twidere.util.ParseUtils; import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener; +import org.mariotaku.twidere.util.UserColorNicknameUtils; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.menu.TwidereMenuInfo; import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent; @@ -113,7 +115,7 @@ import org.mariotaku.twidere.util.message.TaskStateChangedEvent; import org.mariotaku.twidere.view.HeaderDrawerLayout; import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback; import org.mariotaku.twidere.view.ProfileBannerImageView; -import org.mariotaku.twidere.view.ProfileImageView; +import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.TabPagerIndicator; import org.mariotaku.twidere.view.TintedStatusFrameLayout; import org.mariotaku.twidere.view.iface.IColorLabelView; @@ -131,7 +133,6 @@ import static org.mariotaku.twidere.util.UserColorNicknameUtils.clearUserColor; import static org.mariotaku.twidere.util.UserColorNicknameUtils.clearUserNickname; import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor; import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname; -import static org.mariotaku.twidere.util.UserColorNicknameUtils.setUserColor; import static org.mariotaku.twidere.util.Utils.addIntentToMenu; import static org.mariotaku.twidere.util.Utils.formatToLongTimeString; import static org.mariotaku.twidere.util.Utils.getAccountColor; @@ -143,8 +144,10 @@ import static org.mariotaku.twidere.util.Utils.getOriginalTwitterProfileImage; import static org.mariotaku.twidere.util.Utils.getTwitterInstance; import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes; import static org.mariotaku.twidere.util.Utils.openImage; +import static org.mariotaku.twidere.util.Utils.openMutesUsers; import static org.mariotaku.twidere.util.Utils.openStatus; import static org.mariotaku.twidere.util.Utils.openTweetSearch; +import static org.mariotaku.twidere.util.Utils.openUserBlocks; import static org.mariotaku.twidere.util.Utils.openUserFollowers; import static org.mariotaku.twidere.util.Utils.openUserFriends; import static org.mariotaku.twidere.util.Utils.openUserLists; @@ -153,9 +156,8 @@ import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability; import static org.mariotaku.twidere.util.Utils.showInfoMessage; public class UserFragment extends BaseSupportFragment implements OnClickListener, - OnMenuItemClickListener, OnLinkClickListener, OnSizeChangedListener, - OnSharedPreferenceChangeListener, OnTouchListener, DrawerCallback, SupportFragmentCallback, - SystemWindowsInsetsCallback { + OnLinkClickListener, OnSizeChangedListener, OnSharedPreferenceChangeListener, + OnTouchListener, DrawerCallback, SupportFragmentCallback, SystemWindowsInsetsCallback { public static final String TRANSITION_NAME_PROFILE_IMAGE = "profile_image"; public static final String TRANSITION_NAME_PROFILE_TYPE = "profile_type"; @@ -166,7 +168,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener private ImageLoaderWrapper mProfileImageLoader; - private ProfileImageView mProfileImageView; + private ShapedImageView mProfileImageView; private ImageView mProfileTypeView; private ProfileBannerImageView mProfileBannerView; private TextView mNameView, mScreenNameView, mDescriptionView, mLocationView, mURLView, mCreatedAtView, @@ -254,7 +256,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener public void onLoadFinished(final Loader> loader, final SingleResponse data) { if (getActivity() == null) return; - if (data.getData() != null && data.getData().id > 0) { + if (data.hasData()) { final ParcelableUser user = data.getData(); mCardContent.setVisibility(View.VISIBLE); mErrorRetryContainer.setVisibility(View.GONE); @@ -319,13 +321,39 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mFollowButton.setText(R.string.edit); mFollowButton.setVisibility(View.VISIBLE); } else if (relationship != null) { + final int drawableRes; if (relationship.isSourceBlockingTarget()) { mFollowButton.setText(R.string.unblock); + drawableRes = R.drawable.ic_follow_blocked; } else if (relationship.isSourceFollowingTarget()) { mFollowButton.setText(R.string.unfollow); + if (relationship.isTargetFollowingSource()) { + drawableRes = R.drawable.ic_follow_bidirectional; + } else { + drawableRes = R.drawable.ic_follow_outgoing; + } + } else if (user.is_follow_request_sent) { + mFollowButton.setText(R.string.requested); + if (relationship.isTargetFollowingSource()) { + drawableRes = R.drawable.ic_follow_incoming; + } else { + drawableRes = R.drawable.ic_follow_requested; + } } else { mFollowButton.setText(R.string.follow); + if (relationship.isTargetFollowingSource()) { + drawableRes = R.drawable.ic_follow_incoming; + } else { + drawableRes = R.drawable.ic_follow_none; + } } + final Drawable icon = getResources().getDrawable(drawableRes); + final int iconSize = Math.round(mFollowButton.getTextSize() * 1.4f); + icon.setBounds(0, 0, iconSize, iconSize); + icon.setColorFilter(mFollowButton.getCurrentTextColor(), Mode.SRC_ATOP); + mFollowButton.setCompoundDrawables(icon, null, null, null); + mFollowButton.setCompoundDrawablePadding(Math.round(mFollowButton.getTextSize() * 0.25f)); + final ContentResolver resolver = getContentResolver(); final String where = Expression.equals(CachedUsers.USER_ID, user.id).getSQL(); resolver.delete(CachedUsers.CONTENT_URI, where, null); @@ -378,7 +406,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mDescriptionContainer.setVisibility(userIsMe || !isEmpty(user.description_html) ? View.VISIBLE : View.GONE); mDescriptionView.setText(user.description_html != null ? Html.fromHtml(user.description_html) : null); final TwidereLinkify linkify = new TwidereLinkify(this); - linkify.setLinkTextColor(user.link_color); linkify.applyAllLinks(mDescriptionView, user.account_id, false); mDescriptionView.setMovementMethod(null); mLocationContainer.setVisibility(userIsMe || !isEmpty(user.location) ? View.VISIBLE : View.GONE); @@ -386,7 +413,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mURLContainer.setVisibility(userIsMe || !isEmpty(user.url) || !isEmpty(user.url_expanded) ? View.VISIBLE : View.GONE); mURLView.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded); - mURLView.setLinkTextColor(user.link_color); mURLView.setMovementMethod(null); final String createdAt = formatToLongTimeString(activity, user.created_at); final float daysSinceCreated = (System.currentTimeMillis() - user.created_at) / 1000 / 60 / 60 / 24; @@ -399,11 +425,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener if (userColor != 0) { mProfileImageLoader.displayProfileImage(mProfileImageView, getOriginalTwitterProfileImage(user.profile_image_url)); - setupUserColorActionBar(userColor); + setUserColor(userColor); } else { mProfileImageLoader.displayProfileImage(mProfileImageView, getOriginalTwitterProfileImage(user.profile_image_url)); - setupUserColorActionBar(user.link_color); + setUserColor(user.link_color); } final int defWidth = res.getDisplayMetrics().widthPixels; final int width = mBannerWidth > 0 ? mBannerWidth : defWidth; @@ -534,7 +560,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener if (resultCode == Activity.RESULT_OK) { if (data == null) return; final int color = data.getIntExtra(EXTRA_COLOR, Color.TRANSPARENT); - setUserColor(getActivity(), mUser.id, color); + UserColorNicknameUtils.setUserColor(getActivity(), mUser.id, color); } else if (resultCode == ColorPickerDialogActivity.RESULT_CLEARED) { clearUserColor(getActivity(), mUser.id); } @@ -619,6 +645,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mProfileBannerView.setOnSizeChangedListener(this); mProfileBannerSpace.setOnTouchListener(this); + + mCardView.setCardBackgroundColor(ThemeUtils.getCardBackgroundColor(getActivity())); + getUserInfo(accountId, userId, screenName, false); setupBaseActionBar(); @@ -673,12 +702,198 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener @Override public void onPrepareOptionsMenu(final Menu menu) { if (!shouldUseNativeMenu() || !menu.hasVisibleItems()) return; - setMenu(menu); + final AsyncTwitterWrapper twitter = getTwitterWrapper(); + final ParcelableUser user = mUser; + final Relationship relationship = mRelationship; + if (twitter == null || user == null) return; + final boolean isMyself = user.account_id == user.id; + final MenuItem mentionItem = menu.findItem(MENU_MENTION); + if (mentionItem != null) { + mentionItem.setTitle(getString(R.string.mention_user_name, getDisplayName(getActivity(), user))); + } + Utils.setMenuItemAvailability(menu, MENU_MENTION, !isMyself); +// final MenuItem followItem = menu.findItem(MENU_FOLLOW); +// followItem.setVisible(!isMyself); +// final boolean shouldShowFollowItem = !creatingFriendship && !destroyingFriendship && !isMyself +// && relationship != null; +// followItem.setEnabled(shouldShowFollowItem); +// if (shouldShowFollowItem) { +// followItem.setTitle(isFollowing ? R.string.unfollow : isProtected ? R.string.send_follow_request +// : R.string.follow); +// followItem.setIcon(isFollowing ? R.drawable.ic_action_cancel : R.drawable.ic_action_add); +// } else { +// followItem.setTitle(null); +// followItem.setIcon(null); +// } + if (!isMyself && relationship != null) { + setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, relationship.canSourceDMTarget()); + setMenuItemAvailability(menu, MENU_BLOCK, true); + setMenuItemAvailability(menu, MENU_MUTE_USER, true); + final MenuItem blockItem = menu.findItem(MENU_BLOCK); + if (blockItem != null) { + final boolean blocking = relationship.isSourceBlockingTarget(); + MenuUtils.setMenuInfo(blockItem, new TwidereMenuInfo(blocking)); + blockItem.setTitle(blocking ? R.string.unblock : R.string.block); + } + final MenuItem muteItem = menu.findItem(MENU_MUTE_USER); + if (muteItem != null) { + final boolean muting = relationship.isSourceMutingTarget(); + MenuUtils.setMenuInfo(muteItem, new TwidereMenuInfo(muting)); + muteItem.setTitle(muting ? R.string.unmute : R.string.mute); + } + final MenuItem filterItem = menu.findItem(MENU_ADD_TO_FILTER); + if (filterItem != null) { + final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); + MenuUtils.setMenuInfo(filterItem, new TwidereMenuInfo(filtering)); + filterItem.setTitle(filtering ? R.string.remove_from_filter : R.string.add_to_filter); + } + } else { + setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, false); + setMenuItemAvailability(menu, MENU_BLOCK, false); + setMenuItemAvailability(menu, MENU_MUTE_USER, false); + setMenuItemAvailability(menu, MENU_REPORT_SPAM, false); + } + setMenuItemAvailability(menu, R.id.muted_users, isMyself); + setMenuItemAvailability(menu, R.id.blocked_users, isMyself); + final Intent intent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER); + final Bundle extras = new Bundle(); + extras.putParcelable(EXTRA_USER, user); + intent.putExtras(extras); + menu.removeGroup(MENU_GROUP_USER_EXTENSION); + addIntentToMenu(getActivity(), menu, intent, MENU_GROUP_USER_EXTENSION); } @Override public boolean onOptionsItemSelected(final MenuItem item) { - return handleMenuItemClick(item); + final AsyncTwitterWrapper twitter = getTwitterWrapper(); + final ParcelableUser user = mUser; + final Relationship relationship = mRelationship; + if (user == null || twitter == null) return false; + switch (item.getItemId()) { + case MENU_BLOCK: { + if (mRelationship != null) { + if (mRelationship.isSourceBlockingTarget()) { + twitter.destroyBlockAsync(user.account_id, user.id); + } else { + CreateUserBlockDialogFragment.show(getFragmentManager(), user); + } + } + break; + } + case MENU_REPORT_SPAM: { + ReportSpamDialogFragment.show(getFragmentManager(), user); + break; + } + case MENU_ADD_TO_FILTER: { + final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); + final ContentResolver cr = getContentResolver(); + if (filtering) { + final Expression where = Expression.equals(Filters.Users.USER_ID, user.id); + cr.delete(Filters.Users.CONTENT_URI, where.getSQL(), null); + showInfoMessage(getActivity(), R.string.message_user_unmuted, false); + } else { + cr.insert(Filters.Users.CONTENT_URI, ContentValuesCreator.makeFilteredUserContentValues(user)); + showInfoMessage(getActivity(), R.string.message_user_muted, false); + } + break; + } + case MENU_MUTE_USER: { + if (mRelationship != null) { + if (mRelationship.isSourceMutingTarget()) { + twitter.destroyMuteAsync(user.account_id, user.id); + } else { + CreateUserMuteDialogFragment.show(getFragmentManager(), user); + } + } + break; + } + case MENU_MENTION: { + final Intent intent = new Intent(INTENT_ACTION_MENTION); + final Bundle bundle = new Bundle(); + bundle.putParcelable(EXTRA_USER, user); + intent.putExtras(bundle); + startActivity(intent); + break; + } + case MENU_SEND_DIRECT_MESSAGE: { + final Uri.Builder builder = new Uri.Builder(); + builder.scheme(SCHEME_TWIDERE); + builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION); + builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(user.account_id)); + builder.appendQueryParameter(QUERY_PARAM_USER_ID, String.valueOf(user.id)); + final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); + intent.putExtra(EXTRA_ACCOUNT, ParcelableCredentials.getAccount(getActivity(), user.account_id)); + intent.putExtra(EXTRA_USER, user); + startActivity(intent); + break; + } + case MENU_SET_COLOR: { + final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); + intent.putExtra(EXTRA_COLOR, getUserColor(getActivity(), user.id, true)); + intent.putExtra(EXTRA_ALPHA_SLIDER, false); + intent.putExtra(EXTRA_CLEAR_BUTTON, true); + startActivityForResult(intent, REQUEST_SET_COLOR); + break; + } + case MENU_CLEAR_NICKNAME: { + clearUserNickname(getActivity(), user.id); + break; + } + case MENU_SET_NICKNAME: { + final String nick = getUserNickname(getActivity(), user.id, true); + SetUserNicknameDialogFragment.show(getFragmentManager(), user.id, nick); + break; + } + case MENU_ADD_TO_LIST: { + final Intent intent = new Intent(INTENT_ACTION_SELECT_USER_LIST); + intent.setClass(getActivity(), UserListSelectorActivity.class); + intent.putExtra(EXTRA_ACCOUNT_ID, user.account_id); + intent.putExtra(EXTRA_SCREEN_NAME, getAccountScreenName(getActivity(), user.account_id)); + startActivityForResult(intent, REQUEST_ADD_TO_LIST); + break; + } + case MENU_OPEN_WITH_ACCOUNT: { + final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT); + intent.setClass(getActivity(), AccountSelectorActivity.class); + intent.putExtra(EXTRA_SINGLE_SELECTION, true); + startActivityForResult(intent, REQUEST_SELECT_ACCOUNT); + break; + } + case MENU_FOLLOW: { + if (relationship == null) return false; + final boolean isFollowing = relationship.isSourceFollowingTarget(); + final boolean isCreatingFriendship = twitter.isCreatingFriendship(user.account_id, user.id); + final boolean isDestroyingFriendship = twitter.isDestroyingFriendship(user.account_id, user.id); + if (!isCreatingFriendship && !isDestroyingFriendship) { + if (isFollowing) { + DestroyFriendshipDialogFragment.show(getFragmentManager(), user); + } else { + twitter.createFriendshipAsync(user.account_id, user.id); + } + } + return true; + } + case R.id.muted_users: { + openMutesUsers(getActivity(), user.account_id); + return true; + } + case R.id.blocked_users: { + openUserBlocks(getActivity(), user.account_id); + return true; + } + default: { + if (item.getIntent() != null) { + try { + startActivity(item.getIntent()); + } catch (final ActivityNotFoundException e) { + Log.w(LOGTAG, e); + return false; + } + } + break; + } + } + return true; } @Override @@ -785,12 +1000,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } } - @Override - public boolean onMenuItemClick(final MenuItem item) { - return handleMenuItemClick(item); - - } - @Override public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { if (mUser == null || !ParseUtils.parseString(mUser.id).equals(key)) return; @@ -837,7 +1046,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mFriendsContainer = headerView.findViewById(R.id.friends_container); mFriendsCount = (TextView) headerView.findViewById(R.id.friends_count); mProfileNameContainer = (IColorLabelView) headerView.findViewById(R.id.profile_name_container); - mProfileImageView = (ProfileImageView) headerView.findViewById(R.id.profile_image); + mProfileImageView = (ShapedImageView) headerView.findViewById(R.id.profile_image); mProfileTypeView = (ImageView) headerView.findViewById(R.id.profile_type); mDescriptionContainer = headerView.findViewById(R.id.description_container); mLocationContainer = headerView.findViewById(R.id.location_container); @@ -897,127 +1106,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener getUserInfo(user.account_id, user.id, user.screen_name, omitIntentExtra); } - private boolean handleMenuItemClick(final MenuItem item) { - final AsyncTwitterWrapper twitter = getTwitterWrapper(); - final ParcelableUser user = mUser; - final Relationship relationship = mRelationship; - if (user == null || twitter == null) return false; - switch (item.getItemId()) { - case MENU_BLOCK: { - if (mRelationship != null) { - if (mRelationship.isSourceBlockingTarget()) { - twitter.destroyBlockAsync(user.account_id, user.id); - } else { - CreateUserBlockDialogFragment.show(getFragmentManager(), user); - } - } - break; - } - case MENU_REPORT_SPAM: { - ReportSpamDialogFragment.show(getFragmentManager(), user); - break; - } - case MENU_ADD_TO_FILTER: { - final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); - final ContentResolver cr = getContentResolver(); - if (filtering) { - final Expression where = Expression.equals(Filters.Users.USER_ID, user.id); - cr.delete(Filters.Users.CONTENT_URI, where.getSQL(), null); - showInfoMessage(getActivity(), R.string.message_user_unmuted, false); - } else { - cr.insert(Filters.Users.CONTENT_URI, ContentValuesCreator.makeFilteredUserContentValues(user)); - showInfoMessage(getActivity(), R.string.message_user_muted, false); - } - break; - } - case MENU_MUTE_USER: { - if (mRelationship != null) { - if (mRelationship.isSourceMutingTarget()) { - twitter.destroyMuteAsync(user.account_id, user.id); - } else { - CreateUserMuteDialogFragment.show(getFragmentManager(), user); - } - } - break; - } - case MENU_MENTION: { - final Intent intent = new Intent(INTENT_ACTION_MENTION); - final Bundle bundle = new Bundle(); - bundle.putParcelable(EXTRA_USER, user); - intent.putExtras(bundle); - startActivity(intent); - break; - } - case MENU_SEND_DIRECT_MESSAGE: { - final Uri.Builder builder = new Uri.Builder(); - builder.scheme(SCHEME_TWIDERE); - builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION); - builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(user.account_id)); - builder.appendQueryParameter(QUERY_PARAM_RECIPIENT_ID, String.valueOf(user.id)); - startActivity(new Intent(Intent.ACTION_VIEW, builder.build())); - break; - } - case MENU_SET_COLOR: { - final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); - intent.putExtra(EXTRA_COLOR, getUserColor(getActivity(), user.id, true)); - intent.putExtra(EXTRA_ALPHA_SLIDER, false); - intent.putExtra(EXTRA_CLEAR_BUTTON, true); - startActivityForResult(intent, REQUEST_SET_COLOR); - break; - } - case MENU_CLEAR_NICKNAME: { - clearUserNickname(getActivity(), user.id); - break; - } - case MENU_SET_NICKNAME: { - final String nick = getUserNickname(getActivity(), user.id, true); - SetUserNicknameDialogFragment.show(getFragmentManager(), user.id, nick); - break; - } - case MENU_ADD_TO_LIST: { - final Intent intent = new Intent(INTENT_ACTION_SELECT_USER_LIST); - intent.setClass(getActivity(), UserListSelectorActivity.class); - intent.putExtra(EXTRA_ACCOUNT_ID, user.account_id); - intent.putExtra(EXTRA_SCREEN_NAME, getAccountScreenName(getActivity(), user.account_id)); - startActivityForResult(intent, REQUEST_ADD_TO_LIST); - break; - } - case MENU_OPEN_WITH_ACCOUNT: { - final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT); - intent.setClass(getActivity(), AccountSelectorActivity.class); - intent.putExtra(EXTRA_SINGLE_SELECTION, true); - startActivityForResult(intent, REQUEST_SELECT_ACCOUNT); - break; - } - case MENU_FOLLOW: { - if (relationship == null) return false; - final boolean isFollowing = relationship.isSourceFollowingTarget(); - final boolean isCreatingFriendship = twitter.isCreatingFriendship(user.account_id, user.id); - final boolean isDestroyingFriendship = twitter.isDestroyingFriendship(user.account_id, user.id); - if (!isCreatingFriendship && !isDestroyingFriendship) { - if (isFollowing) { - DestroyFriendshipDialogFragment.show(getFragmentManager(), user); - } else { - twitter.createFriendshipAsync(user.account_id, user.id); - } - } - return true; - } - default: { - if (item.getIntent() != null) { - try { - startActivity(item.getIntent()); - } catch (final ActivityNotFoundException e) { - Log.w(LOGTAG, e); - return false; - } - } - break; - } - } - return true; - } - private boolean isUucky(long userId, String screenName, Parcelable parcelable) { if (userId == UUCKY_ID || UUCKY_SCREEN_NAME.equalsIgnoreCase(screenName)) return true; if (parcelable instanceof ParcelableUser) { @@ -1053,66 +1141,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener } } - private void setMenu(final Menu menu) { - final AsyncTwitterWrapper twitter = getTwitterWrapper(); - final ParcelableUser user = mUser; - final Relationship relationship = mRelationship; - if (twitter == null || user == null) return; - final boolean isMyself = user.account_id == user.id; - final MenuItem mentionItem = menu.findItem(MENU_MENTION); - if (mentionItem != null) { - mentionItem.setTitle(getString(R.string.mention_user_name, getDisplayName(getActivity(), user))); - } - Utils.setMenuItemAvailability(menu, MENU_MENTION, !isMyself); -// final MenuItem followItem = menu.findItem(MENU_FOLLOW); -// followItem.setVisible(!isMyself); -// final boolean shouldShowFollowItem = !creatingFriendship && !destroyingFriendship && !isMyself -// && relationship != null; -// followItem.setEnabled(shouldShowFollowItem); -// if (shouldShowFollowItem) { -// followItem.setTitle(isFollowing ? R.string.unfollow : isProtected ? R.string.send_follow_request -// : R.string.follow); -// followItem.setIcon(isFollowing ? R.drawable.ic_action_cancel : R.drawable.ic_action_add); -// } else { -// followItem.setTitle(null); -// followItem.setIcon(null); -// } - if (!isMyself && relationship != null) { - setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, relationship.canSourceDMTarget()); - setMenuItemAvailability(menu, MENU_BLOCK, true); - setMenuItemAvailability(menu, MENU_MUTE_USER, true); - final MenuItem blockItem = menu.findItem(MENU_BLOCK); - if (blockItem != null) { - final boolean blocking = relationship.isSourceBlockingTarget(); - MenuUtils.setMenuInfo(blockItem, new TwidereMenuInfo(blocking)); - blockItem.setTitle(blocking ? R.string.unblock : R.string.block); - } - final MenuItem muteItem = menu.findItem(MENU_MUTE_USER); - if (muteItem != null) { - final boolean muting = relationship.isSourceMutingTarget(); - MenuUtils.setMenuInfo(muteItem, new TwidereMenuInfo(muting)); - muteItem.setTitle(muting ? R.string.unmute : R.string.mute); - } - final MenuItem filterItem = menu.findItem(MENU_ADD_TO_FILTER); - if (filterItem != null) { - final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); - MenuUtils.setMenuInfo(filterItem, new TwidereMenuInfo(filtering)); - filterItem.setTitle(filtering ? R.string.remove_from_filter : R.string.add_to_filter); - } - } else { - setMenuItemAvailability(menu, MENU_SEND_DIRECT_MESSAGE, false); - setMenuItemAvailability(menu, MENU_BLOCK, false); - setMenuItemAvailability(menu, MENU_MUTE_USER, false); - setMenuItemAvailability(menu, MENU_REPORT_SPAM, false); - } - final Intent intent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER); - final Bundle extras = new Bundle(); - extras.putParcelable(EXTRA_USER, user); - intent.putExtras(extras); - menu.removeGroup(MENU_GROUP_USER_EXTENSION); - addIntentToMenu(getActivity(), menu, intent, MENU_GROUP_USER_EXTENSION); - } - private void setupBaseActionBar() { final FragmentActivity activity = getActivity(); if (!(activity instanceof LinkHandlerActivity)) return; @@ -1128,13 +1156,16 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener actionBar.setBackgroundDrawable(mActionBarBackground); } - private void setupUserColorActionBar(int color) { + private void setUserColor(int color) { if (mActionBarBackground == null) { setupBaseActionBar(); } mActionBarBackground.setColor(color); mTintedStatusContent.setColor(color, ThemeUtils.getThemeAlpha(getActivity())); mPagerIndicator.setStripColor(color); + mDescriptionView.setLinkTextColor(color); + mLocationView.setLinkTextColor(color); + mURLView.setLinkTextColor(color); } private void setupUserPages() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java index bbebf3dd9..ead46058b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/support/ParcelableUserLoader.java @@ -92,7 +92,6 @@ public final class ParcelableUserLoader extends AsyncTaskLoader data) { - super(context, account_id, data); - mQuery = query; - mPage = page; - } + public UserSearchLoader(final Context context, final long account_id, final String query, final int page, + final List data) { + super(context, account_id, data); + mQuery = query; + mPage = page; + } - @Override - public List getUsers(final Twitter twitter) throws TwitterException { - if (twitter == null) return null; - return twitter.searchUsers(mQuery, mPage); - } + public String getQuery() { + return mQuery; + } - protected long getUserPosition(final User user, final int index) { - return (mPage + 1) * 20 + index; - } + @Override + public List getUsers(final Twitter twitter) throws TwitterException { + if (twitter == null) return null; + return twitter.searchUsers(mQuery, mPage); + } + + protected long getUserPosition(final User user, final int index) { + return (mPage + 1) * 20 + index; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/menu/StatusShareProvider.java b/twidere/src/main/java/org/mariotaku/twidere/menu/StatusShareProvider.java index d16e8c627..c196bdfd1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/menu/StatusShareProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/menu/StatusShareProvider.java @@ -46,12 +46,12 @@ public class StatusShareProvider extends ActionProvider implements Constants { } @Override - public View onCreateActionView(MenuItem forItem) { + public View onCreateActionView() { return null; } @Override - public View onCreateActionView() { + public View onCreateActionView(MenuItem forItem) { return null; } @@ -60,10 +60,6 @@ public class StatusShareProvider extends ActionProvider implements Constants { return true; } - public void setStatus(ParcelableStatus status) { - mStatus = status; - } - @Override public void onPrepareSubMenu(SubMenu subMenu) { final Intent shareIntent = createStatusShareIntent(mContext, mStatus); @@ -72,4 +68,8 @@ public class StatusShareProvider extends ActionProvider implements Constants { addIntentToMenu(mContext, subMenu, shareIntent, MENU_GROUP_STATUS_SHARE); } } + + public void setStatus(ParcelableStatus status) { + mStatus = status; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java index 8ba217287..8b3785d00 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableUser.java @@ -109,44 +109,40 @@ public class ParcelableUser implements TwidereParcelable, Comparable - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.service; - -import android.annotation.TargetApi; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; -import android.os.Build; -import android.service.dreams.DreamService; -import android.view.View; -import android.view.View.OnSystemUiVisibilityChangeListener; - -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.view.NyanDaydreamView; - -@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) -public class NyanDaydreamService extends DreamService implements Constants, OnSharedPreferenceChangeListener, - OnSystemUiVisibilityChangeListener { - - private NyanDaydreamView mNyanDaydreamView; - private SharedPreferences mPreferences; - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - setContentView(R.layout.nyan_daydream); - mNyanDaydreamView.setOnSystemUiVisibilityChangeListener(this); - updateView(); - } - - @Override - public void onContentChanged() { - super.onContentChanged(); - mNyanDaydreamView = (NyanDaydreamView) findViewById(R.id.nyan); - } - - @Override - public void onCreate() { - super.onCreate(); - mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE); - mPreferences.registerOnSharedPreferenceChangeListener(this); - setInteractive(false); - setFullscreen(true); - setScreenBright(false); - } - - @Override - public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { - if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) { - updateView(); - } - } - - @Override - public void onSystemUiVisibilityChange(final int visibility) { - if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { - finish(); - } - } - - private void updateView() { - if (mPreferences == null) return; - final Resources res = getResources(); - final int def = res.getInteger(R.integer.default_live_wallpaper_scale); - mNyanDaydreamView.setScale(mPreferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def)); - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/NyanWallpaperService.java b/twidere/src/main/java/org/mariotaku/twidere/service/NyanWallpaperService.java deleted file mode 100644 index f2d234082..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/service/NyanWallpaperService.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.service; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; -import android.os.PowerManager; -import android.service.wallpaper.WallpaperService; -import android.view.SurfaceHolder; - -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.util.NyanSurfaceHelper; - -public class NyanWallpaperService extends WallpaperService implements Constants { - - @Override - public Engine onCreateEngine() { - return new NyanWallpaperEngine(); - } - - private Context getContext() { - return this; - } - - private final class NyanWallpaperEngine extends Engine implements OnSharedPreferenceChangeListener { - - private SharedPreferences mPreferences; - private final BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(final Context context, final Intent intent) { - final String action = intent.getAction(); - if (Intent.ACTION_SCREEN_ON.equals(action)) { - if (mHelper == null) return; - mHelper.start(); - } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { - if (mHelper == null) return; - mHelper.stop(); - } - - } - }; - - private NyanSurfaceHelper mHelper; - - @Override - public void onCreate(final SurfaceHolder surfaceHolder) { - super.onCreate(surfaceHolder); - mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE); - mPreferences.registerOnSharedPreferenceChangeListener(this); - mHelper = new NyanSurfaceHelper(getContext()); - final IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - registerReceiver(mScreenReceiver, filter); - } - - @Override - public void onDestroy() { - mPreferences.unregisterOnSharedPreferenceChangeListener(this); - unregisterReceiver(mScreenReceiver); - super.onDestroy(); - } - - @Override - public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { - if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) { - updateSurface(); - } - } - - @Override - public void onSurfaceCreated(final SurfaceHolder holder) { - super.onSurfaceCreated(holder); - holder.addCallback(mHelper); - updateSurface(); - updateHelperState(); - } - - @Override - public void onSurfaceDestroyed(final SurfaceHolder holder) { - mHelper.stop(); - holder.removeCallback(mHelper); - super.onSurfaceDestroyed(holder); - } - - @Override - public void onVisibilityChanged(final boolean visible) { - super.onVisibilityChanged(visible); - if (mHelper != null) { - mHelper.setSkipDrawing(!visible); - } - } - - private void updateHelperState() { - final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); - if (pm.isScreenOn()) { - mHelper.start(); - } else { - mHelper.stop(); - } - } - - private void updateSurface() { - if (mPreferences == null) return; - final Resources res = getResources(); - final int def = res.getInteger(R.integer.default_live_wallpaper_scale); - mHelper.setScale(mPreferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def)); - updateHelperState(); - } - - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/text/TwidereURLSpan.java b/twidere/src/main/java/org/mariotaku/twidere/text/TwidereURLSpan.java index 5cc4a88b3..81d84b9ed 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/text/TwidereURLSpan.java +++ b/twidere/src/main/java/org/mariotaku/twidere/text/TwidereURLSpan.java @@ -19,6 +19,7 @@ package org.mariotaku.twidere.text; +import android.support.annotation.NonNull; import android.text.TextPaint; import android.text.style.URLSpan; import android.view.View; @@ -28,45 +29,43 @@ import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener; public class TwidereURLSpan extends URLSpan implements Constants { - private final int type, highlightStyle, highlightColor; - private final long accountId; - private final String url, orig; - private final boolean sensitive; - private final OnLinkClickListener listener; + private final int type, highlightStyle; + private final long accountId; + private final String url, orig; + private final boolean sensitive; + private final OnLinkClickListener listener; - public TwidereURLSpan(final String url, final long accountId, final int type, final boolean sensitive, - final OnLinkClickListener listener, final int highlightStyle, final int highlightColor) { - this(url, null, accountId, type, sensitive, listener, highlightStyle, highlightColor); - } + public TwidereURLSpan(final String url, final long accountId, final int type, final boolean sensitive, + final OnLinkClickListener listener, final int highlightStyle) { + this(url, null, accountId, type, sensitive, listener, highlightStyle); + } - public TwidereURLSpan(final String url, final String orig, final long accountId, final int type, - final boolean sensitive, final OnLinkClickListener listener, final int highlightStyle, - final int highlightColor) { - super(url); - this.url = url; - this.orig = orig; - this.accountId = accountId; - this.type = type; - this.sensitive = sensitive; - this.listener = listener; - this.highlightStyle = highlightStyle; - this.highlightColor = highlightColor; - } + public TwidereURLSpan(final String url, final String orig, final long accountId, final int type, + final boolean sensitive, final OnLinkClickListener listener, final int highlightStyle) { + super(url); + this.url = url; + this.orig = orig; + this.accountId = accountId; + this.type = type; + this.sensitive = sensitive; + this.listener = listener; + this.highlightStyle = highlightStyle; + } - @Override - public void onClick(final View widget) { - if (listener != null) { - listener.onLinkClick(url, orig, accountId, type, sensitive); - } - } + @Override + public void onClick(@NonNull final View widget) { + if (listener != null) { + listener.onLinkClick(url, orig, accountId, type, sensitive); + } + } - @Override - public void updateDrawState(final TextPaint ds) { - if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE) != 0) { - ds.setUnderlineText(true); - } - if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT) != 0) { - ds.setColor(highlightColor != 0 ? highlightColor : ds.linkColor); - } - } + @Override + public void updateDrawState(@NonNull final TextPaint ds) { + if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE) != 0) { + ds.setUnderlineText(true); + } + if ((highlightStyle & VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT) != 0) { + ds.setColor(ds.linkColor); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index bb07b7fc5..643d73b3a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -96,7 +96,7 @@ import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds; import static org.mariotaku.twidere.util.Utils.getDefaultAccountId; import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase; import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase; -import static org.mariotaku.twidere.util.Utils.getStatusIdsInDatabase; +import static org.mariotaku.twidere.util.Utils.getStatusCountInDatabase; import static org.mariotaku.twidere.util.Utils.getTwitterInstance; import static org.mariotaku.twidere.util.Utils.getUserName; import static org.mariotaku.twidere.util.Utils.truncateMessages; @@ -149,6 +149,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public boolean isDestroyingFavorite(final long accountId, final long statusId) { return mDestroyingFavoriteIds.has(accountId, statusId); } + public boolean isCreatingRetweet(final long accountId, final long statusId) { return mCreatingRetweetIds.has(accountId, statusId); } @@ -2297,8 +2298,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (statuses == null || statuses.isEmpty()) { continue; } - final ArrayList ids_in_db = getStatusIdsInDatabase(mContext, uri, accountId); - final boolean noItemsBefore = ids_in_db.isEmpty(); + final boolean noItemsBefore = getStatusCountInDatabase(mContext, uri, accountId) <= 0; final ContentValues[] values = new ContentValues[statuses.size()]; final long[] statusIds = new long[statuses.size()]; for (int i = 0, j = statuses.size(); i < j; i++) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/NyanSurfaceHelper.java b/twidere/src/main/java/org/mariotaku/twidere/util/NyanSurfaceHelper.java deleted file mode 100644 index 94874394f..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/util/NyanSurfaceHelper.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.util; - -import android.content.Context; -import android.graphics.Canvas; -import android.view.SurfaceHolder; - -public final class NyanSurfaceHelper implements SurfaceHolder.Callback { - - private SurfaceHolder mHolder; - private DrawingThread mThread; - private final NyanDrawingHelper mNyanDrawingHelper; - - public NyanSurfaceHelper(final Context context) { - mNyanDrawingHelper = new NyanDrawingHelper(context); - } - - public SurfaceHolder getHolder() { - return mHolder; - } - - public void setScale(final float scale) { - mNyanDrawingHelper.setScale(scale); - } - - public void setSkipDrawing(final boolean skipDrawing) { - if (mThread != null) { - mThread.setSkipDrawing(skipDrawing); - } - } - - public void start() { - if (mThread != null) return; - mThread = new DrawingThread(this, mNyanDrawingHelper); - mThread.start(); - } - - public void stop() { - if (mThread != null) { - mThread.cancel(); - } - mThread = null; - } - - @Override - public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) { - mNyanDrawingHelper.dispatchSizeChanged(width, height); - } - - @Override - public void surfaceCreated(final SurfaceHolder holder) { - mHolder = holder; - start(); - } - - @Override - public void surfaceDestroyed(final SurfaceHolder holder) { - stop(); - mHolder = null; - } - - private static class DrawingThread extends Thread { - - private final NyanSurfaceHelper mSurfaceHelper; - private final NyanDrawingHelper mDrawingHelper; - private boolean mCancelled; - private boolean mSkipDrawing; - - DrawingThread(final NyanSurfaceHelper surfaceHelper, final NyanDrawingHelper drawingHelper) { - mSurfaceHelper = surfaceHelper; - mDrawingHelper = drawingHelper; - } - - public void cancel() { - mCancelled = true; - } - - @Override - public void run() { - while (!mCancelled) { - final long startTime = System.currentTimeMillis(); - drawFrame(); - final long endTime = System.currentTimeMillis(); - try { - Thread.sleep(Math.max(0, 66 - (endTime - startTime))); - } catch (final InterruptedException e) { - - } - } - } - - public void setSkipDrawing(final boolean skipDrawing) { - mSkipDrawing = skipDrawing; - } - - private void drawFrame() { - final SurfaceHolder holder = mSurfaceHelper.getHolder(); - if (mSkipDrawing || holder == null || holder.isCreating()) return; - final Canvas c = holder.lockCanvas(); - if (c == null) return; - if (mDrawingHelper != null) { - mDrawingHelper.dispatchDraw(c); - } - holder.unlockCanvasAndPost(c); - } - - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/StringUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/StringUtils.java new file mode 100644 index 000000000..ebbf2cfee --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/util/StringUtils.java @@ -0,0 +1,43 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.util; + +import android.support.annotation.NonNull; + +/** + * Created by mariotaku on 14/12/23. + */ +public class StringUtils { + public static boolean regionMatchesIgnoreCase(@NonNull final String string, final int thisStart, + @NonNull final String match, final int start, + final int length) { + return string.substring(thisStart, thisStart + length).equalsIgnoreCase(match.substring(start, start + length)); + } + + + public static boolean startsWithIgnoreCase(@NonNull String string, @NonNull String prefix) { + return startsWithIgnoreCase(string, prefix, 0); + } + + public static boolean startsWithIgnoreCase(@NonNull String string, @NonNull String prefix, + int start) { + return regionMatchesIgnoreCase(string, start, prefix, 0, prefix.length()); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java index 231f6d2ca..7a01763b2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ThemeUtils.java @@ -23,6 +23,7 @@ import android.app.ActionBar; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; @@ -34,6 +35,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; import android.support.annotation.NonNull; +import android.support.v4.graphics.drawable.DrawableCompat; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; @@ -44,18 +46,21 @@ import android.view.ContextThemeWrapper; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.CompoundButton; +import android.widget.ProgressBar; +import android.widget.Switch; import android.widget.TextView; import org.mariotaku.menucomponent.internal.Utils; import org.mariotaku.menucomponent.widget.MenuBar.MenuBarMenuInfo; -import org.mariotaku.refreshnow.widget.RefreshNowConfig; -import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator.IndicatorConfig; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.iface.IThemedActivity; import org.mariotaku.twidere.graphic.ActionBarColorDrawable; import org.mariotaku.twidere.text.ParagraphSpacingSpan; +import org.mariotaku.twidere.util.accessor.ViewAccessor; import org.mariotaku.twidere.util.menu.TwidereMenuInfo; +import org.mariotaku.twidere.view.iface.IThemedView; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -182,42 +187,58 @@ public class ThemeUtils implements Constants { } } - public static IndicatorConfig buildRefreshIndicatorConfig(final Context context) { - final IndicatorConfig.Builder builder = new IndicatorConfig.Builder(context); - final Resources res = context.getResources(); - final float width = 3 * res.getDisplayMetrics().density; - final int themeColor = getUserAccentColor(context); - builder.progressColor(themeColor); - builder.indeterminateColor(themeColor); - builder.progressStrokeWidth(width); - builder.indeterminateStrokeWidth(width); - return builder.build(); + public static View createView(final String name, final Context context, + final AttributeSet attrs) { + return createView(name, context, attrs, 0); } - public static RefreshNowConfig buildRefreshNowConfig(final Context context) { - final RefreshNowConfig.Builder builder = new RefreshNowConfig.Builder(context); - builder.minPullDivisor(2); - builder.extraPullDivisor(1); - builder.maxOverScrollDistance(72); - return builder.build(); - } - - public static View createView(final String name, final Context context, final AttributeSet attrs) { + public static View createView(final String name, final Context context, + final AttributeSet attrs, final int tintColor) { + View view = null; try { - return newViewInstance(name, context, attrs); + view = newViewInstance(name, context, attrs); } catch (final Exception e) { // In this case we want to let the base class take a crack // at it. } for (final String prefix : sClassPrefixList) { try { - return newViewInstance(prefix + name, context, attrs); + view = newViewInstance(prefix + name, context, attrs); } catch (final Exception e) { // In this case we want to let the base class take a crack // at it. } } - return null; + if (view != null) { + applyColorTintForView(view, tintColor); + } + return view; + } + + private static void applyColorTintForView(View view, int tintColor) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + if (view instanceof IThemedView) { + final ColorStateList tintList = ColorStateList.valueOf(tintColor); + ((IThemedView) view).setThemeTintColor(tintList); + } else if (view instanceof ProgressBar) { + final ColorStateList tintList = ColorStateList.valueOf(tintColor); + final ProgressBar progressBar = (ProgressBar) view; + ViewAccessor.setProgressTintList(progressBar, tintList); + ViewAccessor.setProgressBackgroundTintList(progressBar, tintList); + ViewAccessor.setIndeterminateTintList(progressBar, tintList); + } else if (view instanceof Switch) { + final ColorStateList tintList = ColorStateList.valueOf(tintColor); + final Switch switchView = (Switch) view; + DrawableCompat.setTintList(switchView.getThumbDrawable(), tintList); + DrawableCompat.setTintList(switchView.getTrackDrawable(), tintList); + } else if (view instanceof CompoundButton) { + final ColorStateList tintList = ColorStateList.valueOf(tintColor); + final CompoundButton compoundButton = (CompoundButton) view; + ViewAccessor.setButtonTintList(compoundButton, tintList); + } else if (view instanceof TextView) { + final TextView textView = (TextView) view; + textView.setLinkTextColor(tintColor); + } } @@ -326,6 +347,14 @@ public class ThemeUtils implements Constants { return color; } + public static int getCardBackgroundColor(final Context context) { + final TypedArray a = context.obtainStyledAttributes(new int[]{R.attr.cardItemBackgroundColor}); + final int color = a.getColor(0, Color.TRANSPARENT); + a.recycle(); + final int themeAlpha = getThemeAlpha(context); + return themeAlpha << 24 | (0x00FFFFFF & color); + } + public static int getComposeThemeResource(final Context context) { return getComposeThemeResource(getThemeNameOption(context), getDarkActionBarOption(context)); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java index fe6f1b52e..83cb6fdca 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereLinkify.java @@ -19,11 +19,6 @@ package org.mariotaku.twidere.util; -import static org.mariotaku.twidere.util.MediaPreviewUtils.AVAILABLE_IMAGE_SHUFFIX; -import static org.mariotaku.twidere.util.Utils.matcherEnd; -import static org.mariotaku.twidere.util.Utils.matcherGroup; -import static org.mariotaku.twidere.util.Utils.matcherStart; - import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; @@ -43,6 +38,11 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static org.mariotaku.twidere.util.MediaPreviewUtils.AVAILABLE_IMAGE_SHUFFIX; +import static org.mariotaku.twidere.util.Utils.matcherEnd; +import static org.mariotaku.twidere.util.Utils.matcherGroup; +import static org.mariotaku.twidere.util.Utils.matcherStart; + /** * Linkify take a piece of text and a regular expression and turns all of the * regex matches in the text into clickable links. This is particularly useful @@ -59,275 +59,252 @@ import java.util.regex.Pattern; public final class TwidereLinkify implements Constants { - public static final int LINK_TYPE_MENTION = 1; - public static final int LINK_TYPE_HASHTAG = 2; - public static final int LINK_TYPE_LINK = 4; - public static final int LINK_TYPE_LIST = 6; - public static final int LINK_TYPE_CASHTAG = 7; - public static final int LINK_TYPE_USER_ID = 8; - public static final int LINK_TYPE_STATUS = 9; + public static final int LINK_TYPE_MENTION = 1; + public static final int LINK_TYPE_HASHTAG = 2; + public static final int LINK_TYPE_LINK = 4; + public static final int LINK_TYPE_LIST = 6; + public static final int LINK_TYPE_CASHTAG = 7; + public static final int LINK_TYPE_USER_ID = 8; + public static final int LINK_TYPE_STATUS = 9; - public static final int[] ALL_LINK_TYPES = new int[] { LINK_TYPE_LINK, LINK_TYPE_MENTION, LINK_TYPE_HASHTAG, - LINK_TYPE_STATUS, LINK_TYPE_CASHTAG }; + public static final int[] ALL_LINK_TYPES = new int[]{LINK_TYPE_LINK, LINK_TYPE_MENTION, LINK_TYPE_HASHTAG, + LINK_TYPE_STATUS, LINK_TYPE_CASHTAG}; - public static final String AVAILABLE_URL_SCHEME_PREFIX = "(https?:\\/\\/)?"; + public static final String AVAILABLE_URL_SCHEME_PREFIX = "(https?:\\/\\/)?"; - public static final String TWITTER_PROFILE_IMAGES_AVAILABLE_SIZES = "(bigger|normal|mini|reasonably_small)"; - private static final String STRING_PATTERN_TWITTER_PROFILE_IMAGES_NO_SCHEME = "(twimg[\\d\\w\\-]+\\.akamaihd\\.net|[\\w\\d]+\\.twimg\\.com)\\/profile_images\\/([\\d\\w\\-_]+)\\/([\\d\\w\\-_]+)_" - + TWITTER_PROFILE_IMAGES_AVAILABLE_SIZES + "(\\.?" + AVAILABLE_IMAGE_SHUFFIX + ")?"; - private static final String STRING_PATTERN_TWITTER_PROFILE_IMAGES = AVAILABLE_URL_SCHEME_PREFIX - + STRING_PATTERN_TWITTER_PROFILE_IMAGES_NO_SCHEME; + public static final String TWITTER_PROFILE_IMAGES_AVAILABLE_SIZES = "(bigger|normal|mini|reasonably_small)"; + private static final String STRING_PATTERN_TWITTER_PROFILE_IMAGES_NO_SCHEME = "(twimg[\\d\\w\\-]+\\.akamaihd\\.net|[\\w\\d]+\\.twimg\\.com)\\/profile_images\\/([\\d\\w\\-_]+)\\/([\\d\\w\\-_]+)_" + + TWITTER_PROFILE_IMAGES_AVAILABLE_SIZES + "(\\.?" + AVAILABLE_IMAGE_SHUFFIX + ")?"; + private static final String STRING_PATTERN_TWITTER_PROFILE_IMAGES = AVAILABLE_URL_SCHEME_PREFIX + + STRING_PATTERN_TWITTER_PROFILE_IMAGES_NO_SCHEME; - public static final Pattern PATTERN_TWITTER_PROFILE_IMAGES = Pattern.compile(STRING_PATTERN_TWITTER_PROFILE_IMAGES, - Pattern.CASE_INSENSITIVE); + public static final Pattern PATTERN_TWITTER_PROFILE_IMAGES = Pattern.compile(STRING_PATTERN_TWITTER_PROFILE_IMAGES, + Pattern.CASE_INSENSITIVE); - private static final String STRING_PATTERN_TWITTER_STATUS_NO_SCHEME = "((mobile|www)\\.)?twitter\\.com\\/(?:#!\\/)?(\\w+)\\/status(es)?\\/(\\d+)(\\/photo\\/\\d)?\\/?"; - private static final String STRING_PATTERN_TWITTER_STATUS = AVAILABLE_URL_SCHEME_PREFIX - + STRING_PATTERN_TWITTER_STATUS_NO_SCHEME; - public static final Pattern PATTERN_TWITTER_STATUS = Pattern.compile(STRING_PATTERN_TWITTER_STATUS, - Pattern.CASE_INSENSITIVE); - public static final int GROUP_ID_TWITTER_STATUS_SCREEN_NAME = 4; - public static final int GROUP_ID_TWITTER_STATUS_STATUS_ID = 6; + private static final String STRING_PATTERN_TWITTER_STATUS_NO_SCHEME = "((mobile|www)\\.)?twitter\\.com\\/(?:#!\\/)?(\\w+)\\/status(es)?\\/(\\d+)(\\/photo\\/\\d)?\\/?"; + private static final String STRING_PATTERN_TWITTER_STATUS = AVAILABLE_URL_SCHEME_PREFIX + + STRING_PATTERN_TWITTER_STATUS_NO_SCHEME; + public static final Pattern PATTERN_TWITTER_STATUS = Pattern.compile(STRING_PATTERN_TWITTER_STATUS, + Pattern.CASE_INSENSITIVE); + public static final int GROUP_ID_TWITTER_STATUS_SCREEN_NAME = 4; + public static final int GROUP_ID_TWITTER_STATUS_STATUS_ID = 6; - private static final String STRING_PATTERN_TWITTER_LIST_NO_SCHEME = "((mobile|www)\\.)?twitter\\.com\\/(?:#!\\/)?(\\w+)\\/lists\\/(.+)\\/?"; - private static final String STRING_PATTERN_TWITTER_LIST = AVAILABLE_URL_SCHEME_PREFIX - + STRING_PATTERN_TWITTER_LIST_NO_SCHEME; - public static final Pattern PATTERN_TWITTER_LIST = Pattern.compile(STRING_PATTERN_TWITTER_LIST, - Pattern.CASE_INSENSITIVE); + private static final String STRING_PATTERN_TWITTER_LIST_NO_SCHEME = "((mobile|www)\\.)?twitter\\.com\\/(?:#!\\/)?(\\w+)\\/lists\\/(.+)\\/?"; + private static final String STRING_PATTERN_TWITTER_LIST = AVAILABLE_URL_SCHEME_PREFIX + + STRING_PATTERN_TWITTER_LIST_NO_SCHEME; + public static final Pattern PATTERN_TWITTER_LIST = Pattern.compile(STRING_PATTERN_TWITTER_LIST, + Pattern.CASE_INSENSITIVE); - public static final int GROUP_ID_TWITTER_LIST_SCREEN_NAME = 4; - public static final int GROUP_ID_TWITTER_LIST_LIST_NAME = 5; + public static final int GROUP_ID_TWITTER_LIST_SCREEN_NAME = 4; + public static final int GROUP_ID_TWITTER_LIST_LIST_NAME = 5; - private final OnLinkClickListener mOnLinkClickListener; - private final Extractor mExtractor = new Extractor(); - private int mHighlightOption, mHighlightColor; + private final OnLinkClickListener mOnLinkClickListener; + private final Extractor mExtractor = new Extractor(); + private int mHighlightOption; - public TwidereLinkify(final OnLinkClickListener listener) { - this(listener, VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH, 0); - } + public TwidereLinkify(final OnLinkClickListener listener) { + this(listener, VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH); + } - public TwidereLinkify(final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - mOnLinkClickListener = listener; - setHighlightOption(highlightOption); - setLinkTextColor(highlightColor); - } + public TwidereLinkify(final OnLinkClickListener listener, final int highlightOption) { + mOnLinkClickListener = listener; + setHighlightOption(highlightOption); + } - public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive) { - applyAllLinks(view, account_id, sensitive, mOnLinkClickListener, mHighlightOption, mHighlightColor); - } + public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive) { + applyAllLinks(view, account_id, sensitive, mOnLinkClickListener, mHighlightOption); + } - public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive, - final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - view.setMovementMethod(LinkMovementMethod.getInstance()); - final SpannableString string = SpannableString.valueOf(view.getText()); - for (final int type : ALL_LINK_TYPES) { - addLinks(string, account_id, type, sensitive, listener, highlightOption, highlightColor); - } - view.setText(string); - addLinkMovementMethod(view); - } + public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive, + final OnLinkClickListener listener, final int highlightOption) { + view.setMovementMethod(LinkMovementMethod.getInstance()); + final SpannableString string = SpannableString.valueOf(view.getText()); + for (final int type : ALL_LINK_TYPES) { + addLinks(string, account_id, type, sensitive, listener, highlightOption); + } + view.setText(string); + addLinkMovementMethod(view); + } - public final void applyUserProfileLink(final TextView view, final long account_id, final long user_id, - final String screen_name) { - applyUserProfileLink(view, account_id, user_id, screen_name, mOnLinkClickListener, mHighlightOption, - mHighlightColor); - } + public final void applyUserProfileLink(final TextView view, final long accountId, final long userId, + final String screenName) { + applyUserProfileLink(view, accountId, userId, screenName, mOnLinkClickListener); + } - public final void applyUserProfileLink(final TextView view, final long account_id, final long user_id, - final String screen_name, final OnLinkClickListener listener, final int highlightOption, - final int highlightColor) { - view.setMovementMethod(LinkMovementMethod.getInstance()); - final SpannableString string = SpannableString.valueOf(view.getText()); - final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); - for (final URLSpan span : spans) { - string.removeSpan(span); - } - if (user_id > 0) { - applyLink(String.valueOf(user_id), 0, string.length(), string, account_id, LINK_TYPE_USER_ID, false, - listener, highlightOption, highlightColor); - } else if (screen_name != null) { - applyLink(screen_name, 0, string.length(), string, account_id, LINK_TYPE_MENTION, false, listener, - highlightOption, highlightColor); - } - view.setText(string); - addLinkMovementMethod(view); - } + public final void applyUserProfileLink(final TextView view, final long accountId, final long userId, + final String screenName, final OnLinkClickListener listener) { + view.setMovementMethod(LinkMovementMethod.getInstance()); + final SpannableString string = SpannableString.valueOf(view.getText()); + final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); + for (final URLSpan span : spans) { + string.removeSpan(span); + } + if (userId > 0) { + applyLink(String.valueOf(userId), 0, string.length(), string, accountId, LINK_TYPE_USER_ID, false, + listener); + } else if (screenName != null) { + applyLink(screenName, 0, string.length(), string, accountId, LINK_TYPE_MENTION, false, listener); + } + view.setText(string); + addLinkMovementMethod(view); + } - public final void applyUserProfileLinkNoHighlight(final TextView view, final long account_id, final long user_id, - final String screen_name) { - applyUserProfileLink(view, account_id, user_id, screen_name, mOnLinkClickListener, - VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE, mHighlightColor); - } + public void setHighlightOption(final int style) { + mHighlightOption = style; + } - public void setHighlightOption(final int style) { - mHighlightOption = style; - } + private boolean addCashtagLinks(final Spannable spannable, final long account_id, + final OnLinkClickListener listener, final int highlightOption) { + boolean hasMatches = false; + for (final Entity entity : mExtractor.extractCashtagsWithIndices(spannable.toString())) { + final int start = entity.getStart(); + final int end = entity.getEnd(); + applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_CASHTAG, false, listener); + hasMatches = true; + } + return hasMatches; + } - public void setLinkTextColor(final int color) { - mHighlightColor = color; - } + private boolean addHashtagLinks(final Spannable spannable, final long account_id, + final OnLinkClickListener listener, final int highlightOption) { + boolean hasMatches = false; + for (final Entity entity : mExtractor.extractHashtagsWithIndices(spannable.toString())) { + final int start = entity.getStart(); + final int end = entity.getEnd(); + applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_HASHTAG, false, listener); + hasMatches = true; + } + return hasMatches; + } - private final boolean addCashtagLinks(final Spannable spannable, final long account_id, - final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - boolean hasMatches = false; - for (final Entity entity : mExtractor.extractCashtagsWithIndices(spannable.toString())) { - final int start = entity.getStart(); - final int end = entity.getEnd(); - applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_CASHTAG, false, listener, - highlightOption, highlightColor); - hasMatches = true; - } - return hasMatches; - } + /** + * Applies a regex to the text of a TextView turning the matches into links. + * If links are found then UrlSpans are applied to the link text match + * areas, and the movement method for the text is changed to + * LinkMovementMethod. + * + * @param highlightOption + * @param listener + */ + private void addLinks(final SpannableString string, final long accountId, final int type, + final boolean sensitive, final OnLinkClickListener listener, final int highlightOption) { + switch (type) { + case LINK_TYPE_MENTION: { + addMentionOrListLinks(string, accountId, listener); + break; + } + case LINK_TYPE_HASHTAG: { + addHashtagLinks(string, accountId, listener, highlightOption); + break; + } + case LINK_TYPE_LINK: { + final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); + for (final URLSpan span : spans) { + final int start = string.getSpanStart(span); + final int end = string.getSpanEnd(span); + if (start < 0 || end > string.length() || start > end) { + continue; + } + string.removeSpan(span); + applyLink(span.getURL(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener); + } + final List urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string)); + for (final Extractor.Entity entity : urls) { + final int start = entity.getStart(), end = entity.getEnd(); + if (entity.getType() != Extractor.Entity.Type.URL + || string.getSpans(start, end, URLSpan.class).length > 0) { + continue; + } + applyLink(entity.getValue(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener); + } + break; + } + case LINK_TYPE_STATUS: { + final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); + for (final URLSpan span : spans) { + final Matcher matcher = PATTERN_TWITTER_STATUS.matcher(span.getURL()); + if (matcher.matches()) { + final int start = string.getSpanStart(span); + final int end = string.getSpanEnd(span); + final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID); + string.removeSpan(span); + applyLink(url, start, end, string, accountId, LINK_TYPE_STATUS, sensitive, listener); + } + } + break; + } + case LINK_TYPE_CASHTAG: { + addCashtagLinks(string, accountId, listener, highlightOption); + break; + } + default: { + return; + } - private final boolean addHashtagLinks(final Spannable spannable, final long account_id, - final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - boolean hasMatches = false; - for (final Entity entity : mExtractor.extractHashtagsWithIndices(spannable.toString())) { - final int start = entity.getStart(); - final int end = entity.getEnd(); - applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_HASHTAG, false, listener, - highlightOption, highlightColor); - hasMatches = true; - } - return hasMatches; - } + } + } - /** - * Applies a regex to the text of a TextView turning the matches into links. - * If links are found then UrlSpans are applied to the link text match - * areas, and the movement method for the text is changed to - * LinkMovementMethod. - * - * @param highlightColor - * @param highlightOption - * @param listener - * - */ - private final void addLinks(final SpannableString string, final long accountId, final int type, - final boolean sensitive, final OnLinkClickListener listener, final int highlightOption, - final int highlightColor) { - switch (type) { - case LINK_TYPE_MENTION: { - addMentionOrListLinks(string, accountId, listener, highlightOption, highlightColor); - break; - } - case LINK_TYPE_HASHTAG: { - addHashtagLinks(string, accountId, listener, highlightOption, highlightColor); - break; - } - case LINK_TYPE_LINK: { - final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); - for (final URLSpan span : spans) { - final int start = string.getSpanStart(span); - final int end = string.getSpanEnd(span); - if (start < 0 || end > string.length() || start > end) { - continue; - } - string.removeSpan(span); - applyLink(span.getURL(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener, - highlightOption, highlightColor); - } - final List urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string)); - for (final Extractor.Entity entity : urls) { - final int start = entity.getStart(), end = entity.getEnd(); - if (entity.getType() != Extractor.Entity.Type.URL - || string.getSpans(start, end, URLSpan.class).length > 0) { - continue; - } - applyLink(entity.getValue(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener, - highlightOption, highlightColor); - } - break; - } - case LINK_TYPE_STATUS: { - final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); - for (final URLSpan span : spans) { - final Matcher matcher = PATTERN_TWITTER_STATUS.matcher(span.getURL()); - if (matcher.matches()) { - final int start = string.getSpanStart(span); - final int end = string.getSpanEnd(span); - final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID); - string.removeSpan(span); - applyLink(url, start, end, string, accountId, LINK_TYPE_STATUS, sensitive, listener, - highlightOption, highlightColor); - } - } - break; - } - case LINK_TYPE_CASHTAG: { - addCashtagLinks(string, accountId, listener, highlightOption, highlightColor); - break; - } - default: { - return; - } + private boolean addMentionOrListLinks(final Spannable spannable, final long accountId, + final OnLinkClickListener listener) { + boolean hasMatches = false; + // Extract lists from status text + final Matcher matcher = Regex.VALID_MENTION_OR_LIST.matcher(spannable); + while (matcher.find()) { + final int start = matcherStart(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_AT); + final int username_end = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); + final int listStart = matcherStart(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); + final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); + final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); + final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); + applyLink(username, start, username_end, spannable, accountId, LINK_TYPE_MENTION, false, listener); + if (listStart >= 0 && listEnd >= 0) { + applyLink(String.format("%s/%s", username, list.substring(list.startsWith("/") ? 1 : 0)), listStart, + listEnd, spannable, accountId, LINK_TYPE_LIST, false, listener); + } + hasMatches = true; + } + // Extract lists from twitter.com links. + final URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class); + for (final URLSpan span : spans) { + final Matcher m = PATTERN_TWITTER_LIST.matcher(span.getURL()); + if (m.matches()) { + final int start = spannable.getSpanStart(span); + final int end = spannable.getSpanEnd(span); + final String screenName = matcherGroup(m, GROUP_ID_TWITTER_LIST_SCREEN_NAME); + final String listName = matcherGroup(m, GROUP_ID_TWITTER_LIST_LIST_NAME); + spannable.removeSpan(span); + applyLink(screenName + "/" + listName, start, end, spannable, accountId, LINK_TYPE_LIST, false, + listener); + hasMatches = true; + } + } + return hasMatches; + } - } - } + private void applyLink(final String url, final int start, final int end, final Spannable text, + final long accountId, final int type, final boolean sensitive, + final OnLinkClickListener listener) { + applyLink(url, null, start, end, text, accountId, type, sensitive, listener); + } - private final boolean addMentionOrListLinks(final Spannable spannable, final long accountId, - final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - boolean hasMatches = false; - // Extract lists from status text - final Matcher matcher = Regex.VALID_MENTION_OR_LIST.matcher(spannable); - while (matcher.find()) { - final int start = matcherStart(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_AT); - final int username_end = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); - final int listStart = matcherStart(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); - final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); - final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); - final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); - applyLink(username, start, username_end, spannable, accountId, LINK_TYPE_MENTION, false, listener, - highlightOption, highlightColor); - if (listStart >= 0 && listEnd >= 0) { - applyLink(String.format("%s/%s", username, list.substring(list.startsWith("/") ? 1 : 0)), listStart, - listEnd, spannable, accountId, LINK_TYPE_LIST, false, listener, highlightOption, highlightColor); - } - hasMatches = true; - } - // Extract lists from twitter.com links. - final URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class); - for (final URLSpan span : spans) { - final Matcher m = PATTERN_TWITTER_LIST.matcher(span.getURL()); - if (m.matches()) { - final int start = spannable.getSpanStart(span); - final int end = spannable.getSpanEnd(span); - final String screenName = matcherGroup(m, GROUP_ID_TWITTER_LIST_SCREEN_NAME); - final String listName = matcherGroup(m, GROUP_ID_TWITTER_LIST_LIST_NAME); - spannable.removeSpan(span); - applyLink(screenName + "/" + listName, start, end, spannable, accountId, LINK_TYPE_LIST, false, - listener, highlightOption, highlightColor); - hasMatches = true; - } - } - return hasMatches; - } + private void applyLink(final String url, final String orig, final int start, final int end, + final Spannable text, final long accountId, final int type, final boolean sensitive, + final OnLinkClickListener listener) { + final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountId, type, sensitive, listener, + mHighlightOption); + text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } - private final void applyLink(final String url, final int start, final int end, final Spannable text, - final long accountId, final int type, final boolean sensitive, final OnLinkClickListener listener, - final int highlightOption, final int highlightColor) { - applyLink(url, null, start, end, text, accountId, type, sensitive, listener, highlightOption, highlightColor); - } + private static void addLinkMovementMethod(final TextView t) { + final MovementMethod m = t.getMovementMethod(); + if (m == null || !(m instanceof LinkMovementMethod)) { + if (t.getLinksClickable()) { + t.setMovementMethod(LinkMovementMethod.getInstance()); + } + } + } - private final void applyLink(final String url, final String orig, final int start, final int end, - final Spannable text, final long accountId, final int type, final boolean sensitive, - final OnLinkClickListener listener, final int highlightOption, final int highlightColor) { - final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountId, type, sensitive, listener, - highlightOption, highlightColor); - text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - - private static final void addLinkMovementMethod(final TextView t) { - final MovementMethod m = t.getMovementMethod(); - if (m == null || !(m instanceof LinkMovementMethod)) { - if (t.getLinksClickable()) { - t.setMovementMethod(LinkMovementMethod.getInstance()); - } - } - } - - public interface OnLinkClickListener { - public void onLinkClick(String link, String orig, long account_id, int type, boolean sensitive); - } + public interface OnLinkClickListener { + public void onLinkClick(String link, String orig, long account_id, int type, boolean sensitive); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java index b86d53652..19997fdd2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java @@ -40,6 +40,8 @@ import java.util.List; import java.util.Set; import twitter4j.DirectMessage; +import twitter4j.Paging; +import twitter4j.ResponseList; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; @@ -111,6 +113,7 @@ public class TwitterWrapper implements Constants { throw new IllegalArgumentException(); } + @NonNull public static User showUserAlternative(final Twitter twitter, final long id, final String screenName) throws TwitterException { final String searchScreenName; @@ -120,12 +123,29 @@ public class TwitterWrapper implements Constants { searchScreenName = twitter.showFriendship(twitter.getId(), id).getTargetUserScreenName(); } else throw new IllegalArgumentException(); - for (final User user : twitter.searchUsers(searchScreenName, 1)) { - if (user.getId() == id || searchScreenName.equals(user.getScreenName())) return user; + final Paging paging = new Paging(); + paging.count(1); + if (id != -1) { + final ResponseList timeline = twitter.getUserTimeline(id, paging); + for (final Status status : timeline) { + final User user = status.getUser(); + if (user.getId() == id) return user; + } + } else { + final ResponseList timeline = twitter.getUserTimeline(screenName, paging); + for (final Status status : timeline) { + final User user = status.getUser(); + if (searchScreenName.equalsIgnoreCase(user.getScreenName())) + return user; + } } - return null; + for (final User user : twitter.searchUsers(searchScreenName, 1)) { + if (user.getId() == id || searchScreenName.equalsIgnoreCase(user.getScreenName())) return user; + } + throw new TwitterException("can't find user"); } + @NonNull public static User tryShowUser(final Twitter twitter, final long id, final String screenName) throws TwitterException { try { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java index f440040a3..c0dfdf5a3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -91,8 +91,6 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; -import android.view.ViewGroup.LayoutParams; -import android.view.ViewGroup.MarginLayoutParams; import android.view.Window; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -114,12 +112,12 @@ import org.mariotaku.querybuilder.Columns.Column; import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.RawItemArray; +import org.mariotaku.querybuilder.SQLFunctions; import org.mariotaku.querybuilder.SQLQueryBuilder; import org.mariotaku.querybuilder.Selectable; import org.mariotaku.querybuilder.Table; import org.mariotaku.querybuilder.Tables; import org.mariotaku.querybuilder.query.SQLSelectQuery; -import org.mariotaku.refreshnow.widget.RefreshNowListView; import org.mariotaku.twidere.BuildConfig; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; @@ -212,10 +210,10 @@ import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.CRC32; -import java.util.zip.Checksum; import javax.net.ssl.SSLException; @@ -516,18 +514,18 @@ public final class Utils implements Constants, TwitterConstants { .union() .select(true, new Columns(new Column(new Table(table), Statuses._ID))) .from(new Tables(table, Filters.Sources.TABLE_NAME)) - .where(Expression.like(new Column(new Table(table), Statuses.SOURCE), - "%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'%")) + .where(Expression.likeRaw(new Column(new Table(table), Statuses.SOURCE), + "'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'%'")) .union() .select(true, new Columns(new Column(new Table(table), Statuses._ID))) .from(new Tables(table, Filters.Keywords.TABLE_NAME)) - .where(Expression.like(new Column(new Table(table), Statuses.TEXT_PLAIN), - "%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%")) + .where(Expression.likeRaw(new Column(new Table(table), Statuses.TEXT_PLAIN), + "'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")) .union() .select(true, new Columns(new Column(new Table(table), Statuses._ID))) .from(new Tables(table, Filters.Links.TABLE_NAME)) - .where(Expression.like(new Column(new Table(table), Statuses.SOURCE), - "%>%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%%")); + .where(Expression.likeRaw(new Column(new Table(table), Statuses.SOURCE), + "'%>%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%%'")); final Expression filterExpression = Expression.or( Expression.notIn(new Column(new Table(table), Statuses._ID), filteredIdsQueryBuilder.build()), Expression.equals(new Column(new Table(table), Statuses.IS_GAP), 1) @@ -642,7 +640,6 @@ public final class Utils implements Constants, TwitterConstants { adapter.setDisplayProfileImage(pref.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true)); adapter.setDisplayNameFirst(pref.getBoolean(KEY_NAME_FIRST, true)); adapter.setLinkHighlightOption(pref.getString(KEY_LINK_HIGHLIGHT_OPTION, VALUE_LINK_HIGHLIGHT_OPTION_NONE)); - adapter.setLinkHighlightColor(ThemeUtils.getUserLinkTextColor(context)); adapter.setNicknameOnly(pref.getBoolean(KEY_NICKNAME_ONLY, false)); adapter.setTextSize(pref.getInt(KEY_TEXT_SIZE, getDefaultTextSize(context))); adapter.notifyDataSetChanged(); @@ -1919,6 +1916,22 @@ public final class Utils implements Constants, TwitterConstants { .getConfiguration().locale); } + public static long[] getMatchedNicknameIds(final String str, SharedPreferences nicknamePrefs) { + if (isEmpty(str)) return new long[0]; + final List list = new ArrayList<>(); + for (final Entry entry : nicknamePrefs.getAll().entrySet()) { + final String value = ParseUtils.parseString(entry.getValue()); + final long key = ParseUtils.parseLong(entry.getKey(), -1); + if (key == -1 || isEmpty(value)) { + continue; + } + if (StringUtils.startsWithIgnoreCase(value, str)) { + list.add(key); + } + } + return ArrayUtils.fromList(list); + } + public static long[] getNewestMessageIdsFromDatabase(final Context context, final Uri uri) { final long[] account_ids = getActivatedAccountIds(context); return getNewestMessageIdsFromDatabase(context, uri, account_ids); @@ -2156,23 +2169,21 @@ public final class Utils implements Constants, TwitterConstants { return share_format.replace(FORMAT_PATTERN_TITLE, title).replace(FORMAT_PATTERN_TEXT, text != null ? text : ""); } - public static ArrayList getStatusIdsInDatabase(final Context context, final Uri uri, final long account_id) { - final ArrayList list = new ArrayList(); - if (context == null) return list; + public static int getStatusCountInDatabase(final Context context, final Uri uri, final long account_id) { + if (context == null) return -1; final ContentResolver resolver = context.getContentResolver(); final String where = Statuses.ACCOUNT_ID + " = " + account_id; - final String[] projection = new String[]{Statuses.STATUS_ID}; + final String[] projection = new String[]{SQLFunctions.COUNT(Statuses.STATUS_ID)}; final Cursor cur = ContentResolverUtils.query(resolver, uri, projection, where, null, null); - if (cur != null) { - final int idx = cur.getColumnIndexOrThrow(Statuses.STATUS_ID); - cur.moveToFirst(); - while (!cur.isAfterLast()) { - list.add(cur.getLong(idx)); - cur.moveToNext(); + if (cur == null) return -1; + try { + if (cur.moveToFirst()) { + return cur.getInt(0); } + return -1; + } finally { cur.close(); } - return list; } public static int getStatusTypeIconRes(final boolean is_favorite, final boolean has_location, @@ -2612,14 +2623,6 @@ public final class Utils implements Constants, TwitterConstants { return false; } - public static int inferStatusBarHeight(final Activity activity) { - final Window w = activity.getWindow(); - final View decorView = w.getDecorView(); - final Rect rect = new Rect(); - decorView.getWindowVisibleDisplayFrame(rect); - return rect.top; - } - public static void initAccountColor(final Context context) { if (context == null) return; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, new String[]{ @@ -2777,14 +2780,6 @@ public final class Utils implements Constants, TwitterConstants { return retweeted_by_id == account_id || my_retweet_id > 0; } - public static boolean isMyUserName(final Context context, final String screen_name) { - if (context == null) return false; - for (final String account_screen_name : getAccountScreenNames(context)) { - if (account_screen_name.equalsIgnoreCase(screen_name)) return true; - } - return false; - } - public static boolean isNetworkAvailable(final Context context) { final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo info = cm.getActiveNetworkInfo(); @@ -2858,16 +2853,6 @@ public final class Utils implements Constants, TwitterConstants { // SCREENLAYOUT_LAYOUTDIR_RTL; } - public static boolean isSameAccount(final Context context, final long accountId, final long userId) { - if (context == null || accountId <= 0 || userId <= 0) return false; - return accountId == userId; - } - - public static boolean isSameAccount(final Context context, final long accountId, final String screenName) { - if (context == null || accountId <= 0 || screenName == null) return false; - return screenName.equalsIgnoreCase(getAccountScreenName(context, accountId)); - } - public static boolean isUserLoggedIn(final Context context, final long accountId) { if (context == null) return false; final long[] ids = getAccountIds(context); @@ -2878,7 +2863,7 @@ public final class Utils implements Constants, TwitterConstants { return false; } - public static final int matcherEnd(final Matcher matcher, final int group) { + public static int matcherEnd(final Matcher matcher, final int group) { try { return matcher.end(group); } catch (final IllegalStateException e) { @@ -2887,7 +2872,7 @@ public final class Utils implements Constants, TwitterConstants { return -1; } - public static final String matcherGroup(final Matcher matcher, final int group) { + public static String matcherGroup(final Matcher matcher, final int group) { try { return matcher.group(group); } catch (final IllegalStateException e) { @@ -2896,7 +2881,7 @@ public final class Utils implements Constants, TwitterConstants { return null; } - public static final int matcherStart(final Matcher matcher, final int group) { + public static int matcherStart(final Matcher matcher, final int group) { try { return matcher.start(group); } catch (final IllegalStateException e) { @@ -3966,14 +3951,14 @@ public final class Utils implements Constants, TwitterConstants { final ListView listView = fragment.getListView(); listView.setPadding(insets.left, insets.top, insets.right, insets.bottom); listView.setClipToPadding(false); - if (listView instanceof RefreshNowListView) { - final View indicatorView = ((RefreshNowListView) listView).getRefreshIndicatorView(); - final LayoutParams lp = indicatorView.getLayoutParams(); - if (lp instanceof MarginLayoutParams) { - ((MarginLayoutParams) lp).topMargin = insets.top; - indicatorView.setLayoutParams(lp); - } - } +// if (listView instanceof RefreshNowListView) { +// final View indicatorView = ((RefreshNowListView) listView).getRefreshIndicatorView(); +// final LayoutParams lp = indicatorView.getLayoutParams(); +// if (lp instanceof MarginLayoutParams) { +// ((MarginLayoutParams) lp).topMargin = insets.top; +// indicatorView.setLayoutParams(lp); +// } +// } } public static boolean isFilteringUser(Context context, long userId) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/WindowAccessor.java b/twidere/src/main/java/org/mariotaku/twidere/util/WindowAccessor.java index ed3e9dd47..f3676f8ac 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/WindowAccessor.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/WindowAccessor.java @@ -13,7 +13,7 @@ public class WindowAccessor { WindowAccessorL.setStatusBarColor(window, color); } - @TargetApi(Build.VERSION_CODES.L) + @TargetApi(Build.VERSION_CODES.LOLLIPOP) private static class WindowAccessorL { public static void setStatusBarColor(Window window, int color) { window.setStatusBarColor(color); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/accessor/ViewAccessor.java b/twidere/src/main/java/org/mariotaku/twidere/util/accessor/ViewAccessor.java index 59b120c25..9b857c922 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/accessor/ViewAccessor.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/accessor/ViewAccessor.java @@ -25,6 +25,8 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.view.ViewCompat; import android.view.View; +import android.widget.CompoundButton; +import android.widget.ProgressBar; public final class ViewAccessor { @@ -34,11 +36,6 @@ public final class ViewAccessor { } } - public static void setBackgroundTintList(final View view, final ColorStateList list) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; - ViewAccessorL.setBackgroundTintList(view, list); - } - @SuppressWarnings("deprecation") public static void setBackground(final View view, final Drawable background) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { @@ -48,6 +45,31 @@ public final class ViewAccessor { } } + public static void setBackgroundTintList(final View view, final ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + ViewAccessorL.setBackgroundTintList(view, list); + } + + public static void setButtonTintList(CompoundButton view, ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + ViewAccessorL.setButtonTintList(view, list); + } + + public static void setIndeterminateTintList(ProgressBar view, ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + ViewAccessorL.setIndeterminateTintList(view, list); + } + + public static void setProgressBackgroundTintList(ProgressBar view, ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + ViewAccessorL.setProgressBackgroundTintList(view, list); + } + + public static void setProgressTintList(ProgressBar view, ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + ViewAccessorL.setProgressTintList(view, list); + } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) static class ViewAccessorJB { static void setBackground(final View view, final Drawable background) { @@ -62,5 +84,25 @@ public final class ViewAccessor { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; view.setBackgroundTintList(list); } + + static void setButtonTintList(final CompoundButton view, final ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + view.setButtonTintList(list); + } + + static void setIndeterminateTintList(final ProgressBar view, final ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + view.setIndeterminateTintList(list); + } + + static void setProgressBackgroundTintList(final ProgressBar view, final ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + view.setProgressBackgroundTintList(list); + } + + static void setProgressTintList(final ProgressBar view, final ColorStateList list) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + view.setProgressTintList(list); + } } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/CardMediaContainer.java b/twidere/src/main/java/org/mariotaku/twidere/view/CardMediaContainer.java new file mode 100644 index 000000000..369c7f164 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/view/CardMediaContainer.java @@ -0,0 +1,211 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.model.ParcelableMedia; +import org.mariotaku.twidere.util.ImageLoaderWrapper; +import org.mariotaku.twidere.util.ImageLoadingHandler; +import org.mariotaku.twidere.util.MediaPreviewUtils.OnMediaClickListener; + +/** + * Created by mariotaku on 14/12/17. + */ +public class CardMediaContainer extends ViewGroup { + + private final int mMaxColumns; + private final int mHorizontalSpacing, mVerticalSpacing; + private int[] mTempIndices; + + public CardMediaContainer(Context context) { + this(context, null); + } + + public CardMediaContainer(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public CardMediaContainer(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mMaxColumns = 3; + final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{ + android.R.attr.horizontalSpacing, android.R.attr.verticalSpacing}); + mHorizontalSpacing = a.getDimensionPixelSize(0, 0); + mVerticalSpacing = a.getDimensionPixelSize(1, 0); + a.recycle(); + } + + + public void displayMedia(@NonNull final int... imageRes) { + for (int i = 0, j = getChildCount(), k = imageRes.length; i < j; i++) { + final View child = getChildAt(i); + final ImageView imageView = (ImageView) child.findViewById(R.id.media_preview); + final View progress = child.findViewById(R.id.media_preview_progress); + progress.setVisibility(GONE); + if (i < k) { + imageView.setImageResource(imageRes[i]); + } else { + imageView.setImageDrawable(null); + child.setVisibility(GONE); + } + } + } + + public void displayMedia(@Nullable final ParcelableMedia[] mediaArray, + @NonNull final ImageLoaderWrapper loader, + final long accountId, + final OnMediaClickListener mediaClickListener, + final ImageLoadingHandler loadingHandler) { + if (mediaArray == null) { + for (int i = 0, j = getChildCount(); i < j; i++) { + final View child = getChildAt(i); + child.setVisibility(GONE); + } + return; + } + final View.OnClickListener clickListener = new ImageGridClickListener(mediaClickListener, accountId); + for (int i = 0, j = getChildCount(), k = mediaArray.length; i < j; i++) { + final View child = getChildAt(i); + child.setOnClickListener(clickListener); + final ImageView imageView = (ImageView) child.findViewById(R.id.media_preview); + if (i < k) { + final ParcelableMedia media = mediaArray[i]; + loader.displayPreviewImage(imageView, media.url, loadingHandler); + child.setVisibility(VISIBLE); + if (i == j - 1) { + final TextView moreIndicator = (TextView) child.findViewById(R.id.more_media); + moreIndicator.setVisibility(j < k ? VISIBLE : GONE); + if (k > j) { + final int extraMediaCount = k - j; + moreIndicator.setText(getResources().getQuantityString(R.plurals.N_media, + extraMediaCount, extraMediaCount)); + } else { + moreIndicator.setText(null); + } + } + } else { + loader.cancelDisplayTask(imageView); + child.setVisibility(GONE); + } + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int[] childIndices = createChildIndices(); + final int childCount = getChildIndicesInLayout(this, childIndices); + if (childCount > 0) { + final double childSqrt = Math.sqrt(childCount); + final int columnCount = (int) (childSqrt % 1 == 0 ? Math.ceil(childSqrt) : Math.min(childCount, mMaxColumns)); + final int rowCount = (int) Math.ceil(childCount / (double) columnCount); + final int firstRowColumnCount = childCount - (columnCount * (rowCount - 1)); + for (int i = 0; i < rowCount; i++) { + final int currColumnCount = i == 0 ? firstRowColumnCount : columnCount; + final int childT; + if (i == 0) { + childT = getPaddingTop(); + } else if (i == 1) { + childT = getChildAt(childIndices[0]).getBottom() + mVerticalSpacing; + } else { + childT = getChildAt(childIndices[firstRowColumnCount + columnCount * (i - 1)]).getBottom() + mVerticalSpacing; + } + for (int j = 0; j < currColumnCount; j++) { + final int childIdx = i == 0 ? j : firstRowColumnCount + columnCount * (i - 1) + j; + final View child = getChildAt(childIndices[childIdx]); + final int childL = j == 0 ? getPaddingLeft() : (getChildAt(childIndices[childIdx - 1]).getRight() + mHorizontalSpacing); + child.layout(childL, childT, childL + child.getMeasuredWidth(), childT + child.getMeasuredHeight()); + } + } + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int measuredWidth = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); + final int contentWidth = measuredWidth - getPaddingLeft() - getPaddingRight(); + final int[] childIndices = createChildIndices(); + final int childCount = getChildIndicesInLayout(this, childIndices); + int heightSum = 0; + if (childCount > 0) { + final double childSqrt = Math.sqrt(childCount); + final int columnCount = (int) (childSqrt % 1 == 0 ? Math.ceil(childSqrt) : Math.min(childCount, mMaxColumns)); + final int rowCount = (int) Math.ceil(childCount / (double) columnCount); + final int firstRowColumnCount = childCount - (columnCount * (rowCount - 1)); + for (int i = 0; i < rowCount; i++) { + final int currColumnCount = i == 0 ? firstRowColumnCount : columnCount; + final int columnWidth = (contentWidth - (mHorizontalSpacing * (currColumnCount - 1))) / currColumnCount; + heightSum = heightSum + columnWidth; + final int childMeasureSpec = MeasureSpec.makeMeasureSpec(columnWidth, MeasureSpec.EXACTLY); + for (int j = 0; j < currColumnCount; j++) { + final int childIdx = i == 0 ? j : firstRowColumnCount + columnCount * (i - 1) + j; + getChildAt(childIndices[childIdx]).measure(childMeasureSpec, childMeasureSpec); + } + } + heightSum = heightSum + (mVerticalSpacing * rowCount - 1); + } + heightSum = heightSum + getPaddingTop() + getPaddingBottom(); + setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(heightSum, MeasureSpec.EXACTLY)); + } + + private int[] createChildIndices() { + if (mTempIndices == null || mTempIndices.length < getChildCount()) { + return mTempIndices = new int[getChildCount()]; + } + return mTempIndices; + } + + private static int getChildIndicesInLayout(ViewGroup viewGroup, int[] indices) { + final int childCount = viewGroup.getChildCount(); + int indicesCount = 0; + for (int i = 0; i < childCount; i++) { + if (viewGroup.getChildAt(i).getVisibility() != GONE) { + indices[indicesCount++] = i; + } + } + return indicesCount; + } + + private static class ImageGridClickListener implements View.OnClickListener { + private final OnMediaClickListener mListener; + private final long mAccountId; + + ImageGridClickListener(final OnMediaClickListener listener, final long accountId) { + mListener = listener; + mAccountId = accountId; + } + + @Override + public void onClick(final View v) { + if (mListener == null) return; + mListener.onMediaClick(v, (ParcelableMedia) v.getTag(), mAccountId); + } + + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ComposeSelectAccountButton.java b/twidere/src/main/java/org/mariotaku/twidere/view/ComposeSelectAccountButton.java index 4cb842af1..b615dd333 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ComposeSelectAccountButton.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ComposeSelectAccountButton.java @@ -225,10 +225,11 @@ public class ComposeSelectAccountButton extends ViewGroup { @Override public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) { final int height = MeasureSpec.getSize(heightSpec), width; - if (getItemCount() > 1) { + final int itemCount = getItemCount(); + if (itemCount > 1) { width = Math.round(height * 1.5f); - } else if (getChildCount() > 0) { - final View firstChild = getChildAt(0); + } else if (itemCount > 0 && state.getItemCount() > 0) { + final View firstChild = recycler.getViewForPosition(0); width = height + firstChild.getPaddingLeft() + firstChild.getPaddingRight(); } else { width = height; diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ForegroundColorView.java b/twidere/src/main/java/org/mariotaku/twidere/view/ForegroundColorView.java index bae2df4ad..8ad37e680 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ForegroundColorView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ForegroundColorView.java @@ -62,7 +62,7 @@ public class ForegroundColorView extends View implements IForegroundView { mAlphaPatternSize = Math.round(getResources().getDisplayMetrics().density * 4); mAlphaRect = new Rect(); mColorRect = new Rect(); - mPaint = new Paint(); + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.color}); setColor(a.getColor(0, Color.TRANSPARENT)); a.recycle(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java b/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java index b53438f78..f625edfec 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/HeaderDrawerLayout.java @@ -271,7 +271,8 @@ public class HeaderDrawerLayout extends ViewGroup { } private void scrollByCallback(float dy) { - setScrollingContentCallback(true); + final int top = getHeaderTop(); + setScrollingContentCallback(top > getHeaderTopMinimum() && top < getHeaderTopMaximum()); mDrawerCallback.scrollBy(dy); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/NyanDaydreamView.java b/twidere/src/main/java/org/mariotaku/twidere/view/NyanDaydreamView.java deleted file mode 100644 index 8916a291e..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/NyanDaydreamView.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.view; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.View; - -import org.mariotaku.twidere.util.NyanDrawingHelper; - -public class NyanDaydreamView extends View { - - private final InvalidateRunnable mInvalidateRunnable; - - private final NyanDrawingHelper mNyanDrawingHelper; - - public NyanDaydreamView(final Context context) { - this(context, null); - } - - public NyanDaydreamView(final Context context, final AttributeSet attrs) { - this(context, attrs, 0); - } - - public NyanDaydreamView(final Context context, final AttributeSet attrs, final int defStyleAttr) { - super(context, attrs, defStyleAttr); - setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - mNyanDrawingHelper = new DreamViewNyanDrawingHelper(this); - mInvalidateRunnable = new InvalidateRunnable(this); - } - - public void setScale(final float scale) { - mNyanDrawingHelper.setScale(scale); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - post(mInvalidateRunnable); - } - - @Override - protected void onDetachedFromWindow() { - removeCallbacks(mInvalidateRunnable); - super.onDetachedFromWindow(); - } - - @Override - protected void onDraw(final Canvas canvas) { - super.onDraw(canvas); - mNyanDrawingHelper.dispatchDraw(canvas); - } - - @Override - protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mNyanDrawingHelper.dispatchSizeChanged(w, h); - } - - private static final class DreamViewNyanDrawingHelper extends NyanDrawingHelper { - - private final int mDisplayHeight; - private final NyanDaydreamView mView; - - public DreamViewNyanDrawingHelper(final NyanDaydreamView view) { - super(view.getContext()); - mView = view; - final Resources res = getResources(); - final DisplayMetrics dm = res.getDisplayMetrics(); - mDisplayHeight = dm.heightPixels; - } - - @Override - protected int getRainbowYOffset() { - final int visibility = mView.getSystemUiVisibility(); - if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0) return 0; - return mDisplayHeight - getHeight(); - } - - } - - private static final class InvalidateRunnable implements Runnable { - - private final View mView; - - InvalidateRunnable(final View view) { - mView = view; - } - - @Override - public void run() { - mView.invalidate(); - mView.postDelayed(this, 66); - } - - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ProfileImageView.java b/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java similarity index 80% rename from twidere/src/main/java/org/mariotaku/twidere/view/ProfileImageView.java rename to twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java index 1d925d5f4..5d26d3f9d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ProfileImageView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java @@ -53,10 +53,10 @@ import org.mariotaku.twidere.R; * An ImageView class with a circle mask so that all images are drawn in a * circle instead of a square. */ -public class ProfileImageView extends ImageView { +public class ShapedImageView extends ImageView { - public static final int STYLE_CIRCLE = 0x1; - public static final int STYLE_RECTANGLE = 0x2; + public static final int SHAPE_CIRCLE = 0x1; + public static final int SHAPE_RECTANGLE = 0x2; private static final int SHADOW_START_COLOR = 0x37000000; @@ -69,27 +69,34 @@ public class ProfileImageView extends ImageView { private final RectF mTempDestination; private final Paint mBitmapPaint; private final Paint mBorderPaint; + private final Paint mBackgroundPaint; private boolean mBorderEnabled; private Bitmap mShadowBitmap; private float mShadowRadius; - private Drawable mBackground; private int mStyle; private float mCornerRadius, mCornerRadiusRatio; - public ProfileImageView(Context context) { + public ShapedImageView(Context context) { this(context, null, 0); } - public ProfileImageView(Context context, AttributeSet attrs) { + public ShapedImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } - public ProfileImageView(Context context, AttributeSet attrs, int defStyle) { + @Override + public void setBackgroundColor(int color) { + mBackgroundPaint.setColor(0xFF000000 | color); + mBackgroundPaint.setAlpha(Color.alpha(color)); + invalidate(); + } + + public ShapedImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ProfileImageView, defStyle, 0); + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShapedImageView, defStyle, 0); mMatrix = new Matrix(); mSource = new RectF(); @@ -103,27 +110,29 @@ public class ProfileImageView extends ImageView { mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBorderPaint.setStyle(Paint.Style.STROKE); - if (a.hasValue(R.styleable.ProfileImageView_pivBorder)) { - setBorderEnabled(a.getBoolean(R.styleable.ProfileImageView_pivBorder, false)); - } else if (a.hasValue(R.styleable.ProfileImageView_pivBorderColor) - || a.hasValue(R.styleable.ProfileImageView_pivBorderWidth)) { + mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + if (a.hasValue(R.styleable.ShapedImageView_sivBorder)) { + setBorderEnabled(a.getBoolean(R.styleable.ShapedImageView_sivBorder, false)); + } else if (a.hasValue(R.styleable.ShapedImageView_sivBorderColor) + || a.hasValue(R.styleable.ShapedImageView_sivBorderWidth)) { setBorderEnabled(true); } - setBorderColor(a.getColor(R.styleable.ProfileImageView_pivBorderColor, Color.TRANSPARENT)); - setBorderWidth(a.getDimensionPixelSize(R.styleable.ProfileImageView_pivBorderWidth, 0)); - setStyle(a.getInt(R.styleable.ProfileImageView_pivStyle, STYLE_RECTANGLE)); - setCornerRadius(a.getDimension(R.styleable.ProfileImageView_pivCornerRadius, 0)); - setCornerRadiusRatio(a.getFraction(R.styleable.ProfileImageView_pivCornerRadiusRatio, 1, 1, -1)); + setBorderColor(a.getColor(R.styleable.ShapedImageView_sivBorderColor, Color.TRANSPARENT)); + setBorderWidth(a.getDimensionPixelSize(R.styleable.ShapedImageView_sivBorderWidth, 0)); + setStyle(a.getInt(R.styleable.ShapedImageView_sivShape, SHAPE_RECTANGLE)); + setCornerRadius(a.getDimension(R.styleable.ShapedImageView_sivCornerRadius, 0)); + setCornerRadiusRatio(a.getFraction(R.styleable.ShapedImageView_sivCornerRadiusRatio, 1, 1, -1)); if (USE_OUTLINE) { - if (a.hasValue(R.styleable.ProfileImageView_pivElevation)) { + if (a.hasValue(R.styleable.ShapedImageView_sivElevation)) { ViewCompat.setElevation(this, - a.getDimensionPixelSize(R.styleable.ProfileImageView_pivElevation, 0)); + a.getDimensionPixelSize(R.styleable.ShapedImageView_sivElevation, 0)); } } else { - mShadowRadius = a.getDimensionPixelSize(R.styleable.ProfileImageView_pivElevation, 0); + mShadowRadius = a.getDimensionPixelSize(R.styleable.ShapedImageView_sivElevation, 0); } - + setBackgroundColor(a.getColor(R.styleable.ShapedImageView_sivBackgroundColor, 0)); a.recycle(); if (USE_OUTLINE) { @@ -185,7 +194,7 @@ public class ProfileImageView extends ImageView { shader.setLocalMatrix(mMatrix); mBitmapPaint.setShader(shader); - if (getStyle() == STYLE_CIRCLE) { + if (getStyle() == SHAPE_CIRCLE) { canvas.drawCircle(dest.centerX(), dest.centerY(), Math.min(dest.width(), dest.height()) / 2f, mBitmapPaint); } else { @@ -224,6 +233,13 @@ public class ProfileImageView extends ImageView { mDestination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); + if (getStyle() == SHAPE_CIRCLE) { + canvas.drawOval(mDestination, mBackgroundPaint); + } else { + final float radius = getCalculatedCornerRadius(); + canvas.drawRoundRect(mDestination, radius, radius, mBackgroundPaint); + } + if (OUTLINE_DRAW) { super.onDraw(canvas); } else { @@ -258,16 +274,12 @@ public class ProfileImageView extends ImageView { mSource.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); - if (mBackground != null) { - mBackground.draw(canvas); - } - drawBitmapWithCircleOnCanvas(bitmap, canvas, mSource, mDestination); } // Then draw the border. if (mBorderEnabled) { - if (getStyle() == STYLE_CIRCLE) { + if (getStyle() == SHAPE_CIRCLE) { canvas.drawCircle(mDestination.centerX(), mDestination.centerY(), mDestination.width() / 2f - mBorderPaint.getStrokeWidth() / 2, mBorderPaint); } else { @@ -290,7 +302,6 @@ public class ProfileImageView extends ImageView { protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); updateShadowBitmap(); - updateBackgroundPadding(); } @Override @@ -301,31 +312,16 @@ public class ProfileImageView extends ImageView { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void setBackground(Drawable background) { - if (OUTLINE_DRAW) { - super.setBackground(background); - return; - } - super.setBackground(null); - mBackground = background; - updateBackgroundPadding(); } @Override public void setBackgroundDrawable(Drawable background) { - if (OUTLINE_DRAW) { - super.setBackgroundDrawable(background); - return; - } - super.setBackgroundDrawable(null); - mBackground = background; - updateBackgroundPadding(); } @Override public void setPadding(int left, int top, int right, int bottom) { super.setPadding(left, top, right, bottom); updateShadowBitmap(); - updateBackgroundPadding(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @@ -333,7 +329,6 @@ public class ProfileImageView extends ImageView { public void setPaddingRelative(int start, int top, int end, int bottom) { super.setPaddingRelative(start, top, end, bottom); updateShadowBitmap(); - updateBackgroundPadding(); } private float getCornerRadius() { @@ -351,23 +346,6 @@ public class ProfileImageView extends ImageView { } } - private void updateBackgroundPadding() { - final Drawable drawable = mBackground; - if (drawable == null) return; - final int width = getWidth(), height = getHeight(); - if (width <= 0 || height <= 0) return; - final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(), - contentRight = width - getPaddingRight(), - contentBottom = height - getPaddingBottom(); - final int contentWidth = contentRight - contentLeft, - contentHeight = contentBottom - contentTop; - final int size = Math.min(contentWidth, contentHeight); - drawable.setBounds(contentLeft + (contentWidth - size) / 2, - contentTop + (contentHeight - size) / 2, - contentRight - (contentWidth - size) / 2, - contentBottom - (contentHeight - size) / 2); - } - private void updateShadowBitmap() { if (USE_OUTLINE) return; final int width = getWidth(), height = getHeight(); @@ -399,8 +377,8 @@ public class ProfileImageView extends ImageView { final int contentLeft = view.getPaddingLeft(), contentTop = view.getPaddingTop(), contentRight = view.getWidth() - view.getPaddingRight(), contentBottom = view.getHeight() - view.getPaddingBottom(); - final ProfileImageView imageView = (ProfileImageView) view; - if (imageView.getStyle() == STYLE_CIRCLE) { + final ShapedImageView imageView = (ShapedImageView) view; + if (imageView.getStyle() == SHAPE_CIRCLE) { final int contentWidth = contentRight - contentLeft, contentHeight = contentBottom - contentTop; final int size = Math.min(contentWidth, contentHeight); diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java b/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java index 9515bb188..2616f300c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ShortTimeView.java @@ -19,9 +19,6 @@ package org.mariotaku.twidere.view; -import static android.text.format.DateUtils.getRelativeTimeSpanString; -import static org.mariotaku.twidere.util.Utils.formatSameDayTime; - import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; @@ -31,93 +28,102 @@ import android.text.format.DateUtils; import android.util.AttributeSet; import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.R; import org.mariotaku.twidere.view.themed.ThemedTextView; +import static android.text.format.DateUtils.getRelativeTimeSpanString; +import static org.mariotaku.twidere.util.Utils.formatSameDayTime; + public class ShortTimeView extends ThemedTextView implements Constants, OnSharedPreferenceChangeListener { - private static final long TICKER_DURATION = 5000L; + private static final long TICKER_DURATION = 5000L; - private final Runnable mTicker; + private final Runnable mTicker; - private boolean mShowAbsoluteTime; - private long mTime; + private boolean mShowAbsoluteTime; + private long mTime; - private final SharedPreferences mPreferences; + private final SharedPreferences mPreferences; - public ShortTimeView(final Context context) { - this(context, null); - } + public ShortTimeView(final Context context) { + this(context, null); + } - public ShortTimeView(final Context context, final AttributeSet attrs) { - this(context, attrs, android.R.attr.textViewStyle); - } + public ShortTimeView(final Context context, final AttributeSet attrs) { + this(context, attrs, android.R.attr.textViewStyle); + } - public ShortTimeView(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); - mTicker = new TickerRunnable(this); - mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - if (mPreferences != null) { - mPreferences.registerOnSharedPreferenceChangeListener(this); - } - updateTimeDisplayOption(); - } + public ShortTimeView(final Context context, final AttributeSet attrs, final int defStyle) { + super(context, attrs, defStyle); + mTicker = new TickerRunnable(this); + mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + if (mPreferences != null) { + mPreferences.registerOnSharedPreferenceChangeListener(this); + } + updateTimeDisplayOption(); + } - @Override - public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { - if (KEY_SHOW_ABSOLUTE_TIME.equals(key)) { - updateTimeDisplayOption(); - invalidateTime(); - } - } + @Override + public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { + if (KEY_SHOW_ABSOLUTE_TIME.equals(key)) { + updateTimeDisplayOption(); + invalidateTime(); + } + } - public void setTime(final long time) { - mTime = time; - invalidateTime(); - } + public void setTime(final long time) { + mTime = time; + invalidateTime(); + } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - post(mTicker); - } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + post(mTicker); + } - @Override - protected void onDetachedFromWindow() { - removeCallbacks(mTicker); - super.onDetachedFromWindow(); - } + @Override + protected void onDetachedFromWindow() { + removeCallbacks(mTicker); + super.onDetachedFromWindow(); + } - private void invalidateTime() { - if (mShowAbsoluteTime) { - setText(formatSameDayTime(getContext(), mTime)); - } else { - setText(getRelativeTimeSpanString(mTime, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, - DateUtils.FORMAT_ABBREV_ALL)); - } - } + private void invalidateTime() { + if (mShowAbsoluteTime) { + setText(formatSameDayTime(getContext(), mTime)); + } else { + final long current = System.currentTimeMillis(); + if (Math.abs(current - mTime) > 60 * 1000) { + setText(getRelativeTimeSpanString(mTime, System.currentTimeMillis(), + DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_ALL)); + } else { + setText(R.string.just_now); + } + } + } - private void updateTimeDisplayOption() { - if (mPreferences == null) return; - mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME, false); - } + private void updateTimeDisplayOption() { + if (mPreferences == null) return; + mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME, false); + } - private static class TickerRunnable implements Runnable { + private static class TickerRunnable implements Runnable { - private final ShortTimeView mTextView; + private final ShortTimeView mTextView; - private TickerRunnable(final ShortTimeView view) { - mTextView = view; - } + private TickerRunnable(final ShortTimeView view) { + mTextView = view; + } - @Override - public void run() { - final Handler handler = mTextView.getHandler(); - if (handler == null) return; - mTextView.invalidateTime(); - final long now = SystemClock.uptimeMillis(); - final long next = now + TICKER_DURATION - now % TICKER_DURATION; - handler.postAtTime(this, next); - } - } + @Override + public void run() { + final Handler handler = mTextView.getHandler(); + if (handler == null) return; + mTextView.invalidateTime(); + final long now = SystemClock.uptimeMillis(); + final long next = now + TICKER_DURATION - now % TICKER_DURATION; + handler.postAtTime(this, next); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/SquareCircularImageView.java b/twidere/src/main/java/org/mariotaku/twidere/view/SquareCircularImageView.java index 5fb7509a6..b823cca9b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/SquareCircularImageView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/SquareCircularImageView.java @@ -23,7 +23,7 @@ import android.content.Context; import android.util.AttributeSet; import android.view.ViewGroup; -public class SquareCircularImageView extends ProfileImageView { +public class SquareCircularImageView extends ShapedImageView { public SquareCircularImageView(final Context context) { this(context, null); diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/TabPagerIndicator.java b/twidere/src/main/java/org/mariotaku/twidere/view/TabPagerIndicator.java index 4004d6143..542dad7db 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/TabPagerIndicator.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/TabPagerIndicator.java @@ -408,7 +408,9 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator { final int count = mIndicator.getCount(); if (count == 0) return; final int parentHeight = mIndicator.getHeight(), parentWidth = mIndicator.getWidth(); - final int width = Math.max(parentWidth / count, child.getMeasuredWidth()); + final int decoratedWidth = getDecoratedMeasuredWidth(child); + final int decoratorWidth = decoratedWidth - child.getMeasuredWidth(); + final int width = Math.max(parentWidth / count - decoratorWidth, decoratedWidth); final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY); final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); child.measure(widthMeasureSpec, heightMeasureSpec); diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/TwidereMenuBar.java b/twidere/src/main/java/org/mariotaku/twidere/view/TwidereMenuBar.java index 9b532d0f0..0f081d81c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/TwidereMenuBar.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/TwidereMenuBar.java @@ -37,7 +37,7 @@ public class TwidereMenuBar extends MenuBar implements MenuBarListener, Constant final int colorLight = resources.getColor(R.color.action_icon_light); mItemColor = Utils.getContrastYIQ(itemBackgroundColor, colorDark, colorLight); mPopupItemColor = Utils.getContrastYIQ(popupItemBackgroundColor, colorDark, colorLight); - mHighlightColor = ThemeUtils.getUserAccentColor(getContext()); + mHighlightColor = isInEditMode() ? 0 : ThemeUtils.getUserAccentColor(getContext()); setMenuBarListener(this); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java index 466bb1059..2da2d2198 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java @@ -21,7 +21,8 @@ import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ImageLoadingHandler; import org.mariotaku.twidere.util.UserColorNicknameUtils; import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.view.ProfileImageView; +import org.mariotaku.twidere.view.CardMediaContainer; +import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.ShortTimeView; import java.util.Locale; @@ -38,14 +39,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick private final IStatusesAdapter adapter; private final ImageView retweetProfileImageView; - private final ProfileImageView profileImageView; + private final ShapedImageView profileImageView; private final ImageView profileTypeView; - private final ImageView mediaPreviewView; private final TextView textView; private final TextView nameView, screenNameView; private final TextView replyRetweetView; private final ShortTimeView timeView; - private final View mediaPreviewContainer; + private final CardMediaContainer mediaPreviewContainer; private final TextView replyCountView, retweetCountView, favoriteCountView; @@ -56,7 +56,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick public StatusViewHolder(IStatusesAdapter adapter, View itemView) { super(itemView); this.adapter = adapter; - profileImageView = (ProfileImageView) itemView.findViewById(R.id.profile_image); + profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image); profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type); textView = (TextView) itemView.findViewById(R.id.text); nameView = (TextView) itemView.findViewById(R.id.name); @@ -65,8 +65,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick replyRetweetView = (TextView) itemView.findViewById(R.id.reply_retweet_status); timeView = (ShortTimeView) itemView.findViewById(R.id.time); - mediaPreviewContainer = itemView.findViewById(R.id.media_preview_container); - mediaPreviewView = (ImageView) itemView.findViewById(R.id.media_preview); + mediaPreviewContainer = (CardMediaContainer) itemView.findViewById(R.id.media_preview_container); replyCountView = (TextView) itemView.findViewById(R.id.reply_count); retweetCountView = (TextView) itemView.findViewById(R.id.retweet_count); @@ -75,7 +74,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick // profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext())); } - public void setupViews() { + public void setupViewListeners() { itemView.findViewById(R.id.item_content).setOnClickListener(this); itemView.findViewById(R.id.item_menu).setOnClickListener(this); @@ -87,6 +86,18 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick favoriteCountView.setOnClickListener(this); } + public void setupViewOptions() { + final float textSize = adapter.getTextSize(); + nameView.setTextSize(textSize); + textView.setTextSize(textSize); + screenNameView.setTextSize(textSize * 0.85f); + timeView.setTextSize(textSize * 0.85f); + replyRetweetView.setTextSize(textSize * 0.75f); + replyCountView.setTextSize(textSize); + replyCountView.setTextSize(textSize); + favoriteCountView.setTextSize(textSize); + } + public void displayStatus(final ParcelableStatus status) { displayStatus(adapter.getContext(), adapter.getImageLoader(), adapter.getImageLoadingHandler(), adapter.getTwitterWrapper(), status); @@ -137,15 +148,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick loader.displayProfileImage(profileImageView, status.user_profile_image_url); - if (media != null && media.length > 0) { - final ParcelableMedia firstMedia = media[0]; - loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url, - status.account_id, handler); - mediaPreviewContainer.setVisibility(View.VISIBLE); - } else { - loader.cancelDisplayTask(mediaPreviewView); - mediaPreviewContainer.setVisibility(View.GONE); - } + mediaPreviewContainer.displayMedia(media, loader, status.account_id, null, handler); if (translation != null) { textView.setText(translation.getText()); } else { @@ -254,19 +257,10 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick loader.displayProfileImage(profileImageView, user_profile_image_url); - if (media != null && media.length > 0) { - final String textUnescaped = cursor.getString(indices.text_unescaped); - final ParcelableMedia firstMedia = media[0]; - textView.setText(textUnescaped); - loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url, - account_id, adapter.getImageLoadingHandler()); - mediaPreviewContainer.setVisibility(View.VISIBLE); - } else { - final String text_unescaped = cursor.getString(indices.text_unescaped); - loader.cancelDisplayTask(mediaPreviewView); - textView.setText(text_unescaped); - mediaPreviewContainer.setVisibility(View.GONE); - } + final String text_unescaped = cursor.getString(indices.text_unescaped); + mediaPreviewContainer.displayMedia(media, loader, account_id, null, + adapter.getImageLoadingHandler()); + textView.setText(text_unescaped); if (reply_count > 0) { replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count)); @@ -310,7 +304,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick return (CardView) itemView.findViewById(R.id.card); } - public ProfileImageView getProfileImageView() { + public ShapedImageView getProfileImageView() { return profileImageView; } @@ -318,6 +312,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick return profileTypeView; } + public void displaySampleStatus() { + nameView.setText("User"); + screenNameView.setText("@user"); + timeView.setTime(System.currentTimeMillis()); + textView.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam faucibus quis purus ac malesuada. Duis id vulputate magna, a eleifend amet."); + mediaPreviewContainer.displayMedia(R.drawable.profile_image_nyan_sakamoto, + R.drawable.profile_image_nyan_sakamoto_santa); + } @Override public void onClick(View v) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/iface/IThemedView.java b/twidere/src/main/java/org/mariotaku/twidere/view/iface/IThemedView.java new file mode 100644 index 000000000..971e60871 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/view/iface/IThemedView.java @@ -0,0 +1,31 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.view.iface; + +import android.content.res.ColorStateList; + +/** + * Created by mariotaku on 14/12/19. + */ +public interface IThemedView { + + public void setThemeTintColor(ColorStateList color); + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedAutoCompleteTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedAutoCompleteTextView.java index 724ce01e4..ac90d82c5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedAutoCompleteTextView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedAutoCompleteTextView.java @@ -20,24 +20,31 @@ package org.mariotaku.twidere.view.themed; import android.content.Context; +import android.content.res.ColorStateList; import android.util.AttributeSet; import android.widget.AutoCompleteTextView; import org.mariotaku.twidere.util.ThemeUtils; +import org.mariotaku.twidere.util.accessor.ViewAccessor; +import org.mariotaku.twidere.view.iface.IThemedView; -public class ThemedAutoCompleteTextView extends AutoCompleteTextView { +public class ThemedAutoCompleteTextView extends AutoCompleteTextView implements IThemedView { - public ThemedAutoCompleteTextView(final Context context) { - this(context, null); - } + public ThemedAutoCompleteTextView(final Context context) { + this(context, null); + } - public ThemedAutoCompleteTextView(final Context context, final AttributeSet attrs) { - this(context, attrs, android.R.attr.editTextStyle); - } + public ThemedAutoCompleteTextView(final Context context, final AttributeSet attrs) { + this(context, attrs, android.R.attr.editTextStyle); + } - public ThemedAutoCompleteTextView(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); + public ThemedAutoCompleteTextView(final Context context, final AttributeSet attrs, final int defStyle) { + super(context, attrs, defStyle); ThemeUtils.initTextView(this); - } + } + @Override + public void setThemeTintColor(ColorStateList color) { + ViewAccessor.setBackgroundTintList(this, color); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedEditText.java b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedEditText.java index 3b2e417fc..0ec7efa05 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedEditText.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedEditText.java @@ -20,12 +20,15 @@ package org.mariotaku.twidere.view.themed; import android.content.Context; +import android.content.res.ColorStateList; import android.util.AttributeSet; import android.widget.EditText; import org.mariotaku.twidere.util.ThemeUtils; +import org.mariotaku.twidere.util.accessor.ViewAccessor; +import org.mariotaku.twidere.view.iface.IThemedView; -public class ThemedEditText extends EditText { +public class ThemedEditText extends EditText implements IThemedView { public ThemedEditText(final Context context) { this(context, null); @@ -40,4 +43,8 @@ public class ThemedEditText extends EditText { ThemeUtils.initTextView(this); } + @Override + public void setThemeTintColor(ColorStateList color) { + ViewAccessor.setBackgroundTintList(this, color); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedMultiAutoCompleteTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedMultiAutoCompleteTextView.java index e9e8ed942..9b8ca5bf5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedMultiAutoCompleteTextView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedMultiAutoCompleteTextView.java @@ -20,24 +20,31 @@ package org.mariotaku.twidere.view.themed; import android.content.Context; +import android.content.res.ColorStateList; import android.util.AttributeSet; import android.widget.MultiAutoCompleteTextView; import org.mariotaku.twidere.util.ThemeUtils; +import org.mariotaku.twidere.util.accessor.ViewAccessor; +import org.mariotaku.twidere.view.iface.IThemedView; -public class ThemedMultiAutoCompleteTextView extends MultiAutoCompleteTextView { +public class ThemedMultiAutoCompleteTextView extends MultiAutoCompleteTextView implements IThemedView { - public ThemedMultiAutoCompleteTextView(final Context context) { - this(context, null); - } + public ThemedMultiAutoCompleteTextView(final Context context) { + this(context, null); + } - public ThemedMultiAutoCompleteTextView(final Context context, final AttributeSet attrs) { - this(context, attrs, android.R.attr.editTextStyle); - } + public ThemedMultiAutoCompleteTextView(final Context context, final AttributeSet attrs) { + this(context, attrs, android.R.attr.editTextStyle); + } - public ThemedMultiAutoCompleteTextView(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); + public ThemedMultiAutoCompleteTextView(final Context context, final AttributeSet attrs, final int defStyle) { + super(context, attrs, defStyle); ThemeUtils.initTextView(this); - } + } + @Override + public void setThemeTintColor(ColorStateList color) { + ViewAccessor.setBackgroundTintList(this, color); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedTextView.java index a96ee9658..6065a4153 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedTextView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/themed/ThemedTextView.java @@ -20,24 +20,30 @@ package org.mariotaku.twidere.view.themed; import android.content.Context; +import android.content.res.ColorStateList; import android.util.AttributeSet; import android.widget.TextView; import org.mariotaku.twidere.util.ThemeUtils; +import org.mariotaku.twidere.view.iface.IThemedView; -public class ThemedTextView extends TextView { +public class ThemedTextView extends TextView implements IThemedView { - public ThemedTextView(final Context context) { - this(context, null); - } + public ThemedTextView(final Context context) { + this(context, null); + } - public ThemedTextView(final Context context, final AttributeSet attrs) { - this(context, attrs, android.R.attr.textViewStyle); - } + public ThemedTextView(final Context context, final AttributeSet attrs) { + this(context, attrs, android.R.attr.textViewStyle); + } - public ThemedTextView(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); + public ThemedTextView(final Context context, final AttributeSet attrs, final int defStyle) { + super(context, attrs, defStyle); ThemeUtils.initTextView(this); - } + } + @Override + public void setThemeTintColor(ColorStateList color) { + setLinkTextColor(color); + } } diff --git a/twidere/src/main/java/twitter4j/TwitterImpl.java b/twidere/src/main/java/twitter4j/TwitterImpl.java index 7dd2adcb4..b013d0640 100644 --- a/twidere/src/main/java/twitter4j/TwitterImpl.java +++ b/twidere/src/main/java/twitter4j/TwitterImpl.java @@ -124,7 +124,8 @@ final class TwitterImpl extends TwitterBaseImpl implements Twitter { ensureAuthorizationEnabled(); final String url = conf.getRestBaseURL() + ENDPOINT_BLOCKS_CREATE; final String signUrl = conf.getSigningRestBaseURL() + ENDPOINT_BLOCKS_CREATE; - return factory.createUser(post(url, signUrl, new HttpParameter("screen_name", screenName), INCLUDE_ENTITIES)); + return factory.createUser(post(url, signUrl, new HttpParameter("screen_name", screenName), + INCLUDE_ENTITIES)); } @Override @@ -132,7 +133,8 @@ final class TwitterImpl extends TwitterBaseImpl implements Twitter { ensureAuthorizationEnabled(); final String url = conf.getRestBaseURL() + ENDPOINT_FAVORITES_CREATE; final String signUrl = conf.getSigningRestBaseURL() + ENDPOINT_FAVORITES_CREATE; - return factory.createStatus(post(url, signUrl, new HttpParameter("id", id), INCLUDE_ENTITIES)); + return factory.createStatus(post(url, signUrl, new HttpParameter("id", id), INCLUDE_ENTITIES, + INCLUDE_REPLY_COUNT, INCLUDE_DESCENDENT_REPLY_COUNT)); } @Override @@ -302,7 +304,7 @@ final class TwitterImpl extends TwitterBaseImpl implements Twitter { ensureAuthorizationEnabled(); return factory.createStatus(post(conf.getRestBaseURL() + ENDPOINT_FAVORITES_DESTROY, conf.getSigningRestBaseURL() + ENDPOINT_FAVORITES_DESTROY, new HttpParameter("id", id), - INCLUDE_ENTITIES)); + INCLUDE_ENTITIES, INCLUDE_REPLY_COUNT, INCLUDE_DESCENDENT_REPLY_COUNT)); } @Override @@ -347,7 +349,8 @@ final class TwitterImpl extends TwitterBaseImpl implements Twitter { public Status destroyStatus(final long statusId) throws TwitterException { ensureAuthorizationEnabled(); return factory.createStatus(post(conf.getRestBaseURL() + "statuses/destroy/" + statusId + ".json", - conf.getSigningRestBaseURL() + "statuses/destroy/" + statusId + ".json", INCLUDE_ENTITIES)); + conf.getSigningRestBaseURL() + "statuses/destroy/" + statusId + ".json", INCLUDE_ENTITIES, + INCLUDE_REPLY_COUNT, INCLUDE_DESCENDENT_REPLY_COUNT)); } @Override diff --git a/twidere/src/main/res/anim/activity_close_enter.xml b/twidere/src/main/res/anim/activity_close_enter.xml index b592460e1..2fe3ed0d7 100644 --- a/twidere/src/main/res/anim/activity_close_enter.xml +++ b/twidere/src/main/res/anim/activity_close_enter.xml @@ -1,24 +1,24 @@ + android:background="@android:color/transparent" + android:duration="@integer/activity_anim_time" + android:fillAfter="true" + android:fillBefore="true" + android:fillEnabled="true" + android:interpolator="@android:interpolator/accelerate_quint" + android:shareInterpolator="false" + android:zAdjustment="top"> - + - + \ No newline at end of file diff --git a/twidere/src/main/res/anim/activity_close_exit.xml b/twidere/src/main/res/anim/activity_close_exit.xml index 467c182d9..f8ebfe376 100644 --- a/twidere/src/main/res/anim/activity_close_exit.xml +++ b/twidere/src/main/res/anim/activity_close_exit.xml @@ -1,12 +1,12 @@ + android:duration="@integer/activity_anim_time" + android:interpolator="@android:interpolator/accelerate_quint" + android:shareInterpolator="false" + android:zAdjustment="top"> - + \ No newline at end of file diff --git a/twidere/src/main/res/anim/activity_open_enter.xml b/twidere/src/main/res/anim/activity_open_enter.xml index c323bc1ab..78922a1e4 100644 --- a/twidere/src/main/res/anim/activity_open_enter.xml +++ b/twidere/src/main/res/anim/activity_open_enter.xml @@ -1,12 +1,12 @@ + android:duration="@integer/activity_anim_time" + android:interpolator="@android:interpolator/decelerate_quint" + android:shareInterpolator="false" + android:zAdjustment="top"> - + \ No newline at end of file diff --git a/twidere/src/main/res/anim/activity_open_exit.xml b/twidere/src/main/res/anim/activity_open_exit.xml index d1bc43222..33af6b965 100644 --- a/twidere/src/main/res/anim/activity_open_exit.xml +++ b/twidere/src/main/res/anim/activity_open_exit.xml @@ -1,24 +1,24 @@ + android:background="@android:color/transparent" + android:duration="@integer/activity_anim_time" + android:fillAfter="true" + android:fillBefore="true" + android:fillEnabled="true" + android:interpolator="@android:interpolator/decelerate_quint" + android:shareInterpolator="false" + android:zAdjustment="normal"> - + - + \ No newline at end of file diff --git a/twidere/src/main/res/drawable-hdpi/ic_action_twitter.png b/twidere/src/main/res/drawable-hdpi/ic_action_twitter.png old mode 100644 new mode 100755 index 852a2e0d8..58dbc6fe0 Binary files a/twidere/src/main/res/drawable-hdpi/ic_action_twitter.png and b/twidere/src/main/res/drawable-hdpi/ic_action_twitter.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_bidirectional.png b/twidere/src/main/res/drawable-hdpi/ic_follow_bidirectional.png new file mode 100644 index 000000000..7bc68d43c Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_bidirectional.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_blocked.png b/twidere/src/main/res/drawable-hdpi/ic_follow_blocked.png new file mode 100644 index 000000000..1491c284a Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_blocked.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_incoming.png b/twidere/src/main/res/drawable-hdpi/ic_follow_incoming.png new file mode 100644 index 000000000..c6d4fae66 Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_incoming.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_none.png b/twidere/src/main/res/drawable-hdpi/ic_follow_none.png new file mode 100644 index 000000000..04ac490ff Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_none.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_outgoing.png b/twidere/src/main/res/drawable-hdpi/ic_follow_outgoing.png new file mode 100644 index 000000000..85a8be3ea Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_outgoing.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_follow_requested.png b/twidere/src/main/res/drawable-hdpi/ic_follow_requested.png new file mode 100644 index 000000000..f91ea15e8 Binary files /dev/null and b/twidere/src/main/res/drawable-hdpi/ic_follow_requested.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_action_twitter.png b/twidere/src/main/res/drawable-mdpi/ic_action_twitter.png old mode 100644 new mode 100755 index a913501fb..e29931632 Binary files a/twidere/src/main/res/drawable-mdpi/ic_action_twitter.png and b/twidere/src/main/res/drawable-mdpi/ic_action_twitter.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_follow_bidirectional.png b/twidere/src/main/res/drawable-mdpi/ic_follow_bidirectional.png new file mode 100644 index 000000000..efb14298e Binary files /dev/null and b/twidere/src/main/res/drawable-mdpi/ic_follow_bidirectional.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_follow_incoming.png b/twidere/src/main/res/drawable-mdpi/ic_follow_incoming.png new file mode 100644 index 000000000..77a538190 Binary files /dev/null and b/twidere/src/main/res/drawable-mdpi/ic_follow_incoming.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_follow_none.png b/twidere/src/main/res/drawable-mdpi/ic_follow_none.png new file mode 100644 index 000000000..923cbb18f Binary files /dev/null and b/twidere/src/main/res/drawable-mdpi/ic_follow_none.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_follow_outgoing.png b/twidere/src/main/res/drawable-mdpi/ic_follow_outgoing.png new file mode 100644 index 000000000..7d2356e46 Binary files /dev/null and b/twidere/src/main/res/drawable-mdpi/ic_follow_outgoing.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_follow_requested.png b/twidere/src/main/res/drawable-mdpi/ic_follow_requested.png new file mode 100644 index 000000000..4b218f7e3 Binary files /dev/null and b/twidere/src/main/res/drawable-mdpi/ic_follow_requested.png differ diff --git a/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto.jpg b/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto.jpg new file mode 100644 index 000000000..ca6f42d39 Binary files /dev/null and b/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto.jpg differ diff --git a/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto_santa.jpg b/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto_santa.jpg new file mode 100644 index 000000000..8fc3e75e2 Binary files /dev/null and b/twidere/src/main/res/drawable-nodpi/profile_image_nyan_sakamoto_santa.jpg differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_action_twitter.png b/twidere/src/main/res/drawable-xhdpi/ic_action_twitter.png old mode 100644 new mode 100755 index 66105b036..7c49f8f9e Binary files a/twidere/src/main/res/drawable-xhdpi/ic_action_twitter.png and b/twidere/src/main/res/drawable-xhdpi/ic_action_twitter.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_bidirectional.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_bidirectional.png new file mode 100644 index 000000000..e0a07a22e Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_bidirectional.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_blocked.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_blocked.png new file mode 100644 index 000000000..fc29a5cd0 Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_blocked.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_incoming.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_incoming.png new file mode 100644 index 000000000..d0885edfc Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_incoming.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_none.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_none.png new file mode 100644 index 000000000..ab1fbdc21 Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_none.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_outgoing.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_outgoing.png new file mode 100644 index 000000000..8fe861f3c Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_outgoing.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_follow_requested.png b/twidere/src/main/res/drawable-xhdpi/ic_follow_requested.png new file mode 100644 index 000000000..b30f62b1f Binary files /dev/null and b/twidere/src/main/res/drawable-xhdpi/ic_follow_requested.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_action_twitter.png b/twidere/src/main/res/drawable-xxhdpi/ic_action_twitter.png old mode 100644 new mode 100755 index b26b990f0..f27800a60 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_action_twitter.png and b/twidere/src/main/res/drawable-xxhdpi/ic_action_twitter.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_bidirectional.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_bidirectional.png new file mode 100644 index 000000000..42622d340 Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_bidirectional.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_blocked.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_blocked.png new file mode 100644 index 000000000..c4e16cdea Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_blocked.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_incoming.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_incoming.png new file mode 100644 index 000000000..c0355f5da Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_incoming.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_none.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_none.png new file mode 100644 index 000000000..697c43a6b Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_none.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_outgoing.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_outgoing.png new file mode 100644 index 000000000..78dfbcf16 Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_outgoing.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_follow_requested.png b/twidere/src/main/res/drawable-xxhdpi/ic_follow_requested.png new file mode 100644 index 000000000..a527a68c2 Binary files /dev/null and b/twidere/src/main/res/drawable-xxhdpi/ic_follow_requested.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_bidirectional.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_bidirectional.png new file mode 100644 index 000000000..a9acb943b Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_bidirectional.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_blocked.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_blocked.png new file mode 100644 index 000000000..c84049646 Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_blocked.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_incoming.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_incoming.png new file mode 100644 index 000000000..4c5f380d8 Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_incoming.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_none.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_none.png new file mode 100644 index 000000000..9a648b3f2 Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_none.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_outgoing.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_outgoing.png new file mode 100644 index 000000000..47fc79a47 Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_outgoing.png differ diff --git a/twidere/src/main/res/drawable-xxxhdpi/ic_follow_requested.png b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_requested.png new file mode 100644 index 000000000..ea7578336 Binary files /dev/null and b/twidere/src/main/res/drawable-xxxhdpi/ic_follow_requested.png differ diff --git a/twidere/src/main/res/drawable/ab_twidere_solid_color_holo.xml b/twidere/src/main/res/drawable/ab_twidere_solid_color_holo.xml index 0c494b3c3..a4a6d83eb 100644 --- a/twidere/src/main/res/drawable/ab_twidere_solid_color_holo.xml +++ b/twidere/src/main/res/drawable/ab_twidere_solid_color_holo.xml @@ -1,8 +1,8 @@ - + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/ab_twidere_solid_dark_holo.xml b/twidere/src/main/res/drawable/ab_twidere_solid_dark_holo.xml index 384cc516a..bf4f7b9ca 100644 --- a/twidere/src/main/res/drawable/ab_twidere_solid_dark_holo.xml +++ b/twidere/src/main/res/drawable/ab_twidere_solid_dark_holo.xml @@ -1,9 +1,9 @@ - - + + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/ab_twidere_solid_light_holo.xml b/twidere/src/main/res/drawable/ab_twidere_solid_light_holo.xml index 23d818eb7..e4c97eb74 100644 --- a/twidere/src/main/res/drawable/ab_twidere_solid_light_holo.xml +++ b/twidere/src/main/res/drawable/ab_twidere_solid_light_holo.xml @@ -1,9 +1,9 @@ - - + + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/bg_map.xml b/twidere/src/main/res/drawable/bg_map.xml index 5caca3547..ddc218ca0 100644 --- a/twidere/src/main/res/drawable/bg_map.xml +++ b/twidere/src/main/res/drawable/bg_map.xml @@ -1,7 +1,7 @@ + android:antialias="true" + android:dither="true" + android:gravity="center" + android:src="@drawable/bg_map_bitmap" + android:tileMode="repeat"/> diff --git a/twidere/src/main/res/drawable/bg_tab_indicator.xml b/twidere/src/main/res/drawable/bg_tab_indicator.xml index ac87a6712..31c39a37a 100644 --- a/twidere/src/main/res/drawable/bg_tab_indicator.xml +++ b/twidere/src/main/res/drawable/bg_tab_indicator.xml @@ -20,8 +20,8 @@ - - + + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/image_preview_error.xml b/twidere/src/main/res/drawable/image_preview_error.xml index 367334ff1..ea430f213 100644 --- a/twidere/src/main/res/drawable/image_preview_error.xml +++ b/twidere/src/main/res/drawable/image_preview_error.xml @@ -1,7 +1,7 @@ + android:antialias="true" + android:dither="true" + android:gravity="center" + android:src="@drawable/image_preview_error_bitmap" + android:tileMode="disabled"/> diff --git a/twidere/src/main/res/drawable/image_preview_nsfw.xml b/twidere/src/main/res/drawable/image_preview_nsfw.xml index 09436919c..a74d42f18 100644 --- a/twidere/src/main/res/drawable/image_preview_nsfw.xml +++ b/twidere/src/main/res/drawable/image_preview_nsfw.xml @@ -1,7 +1,7 @@ + android:antialias="true" + android:dither="true" + android:gravity="center" + android:src="@drawable/image_preview_nsfw_bitmap" + android:tileMode="disabled"/> diff --git a/twidere/src/main/res/drawable/image_preview_refresh.xml b/twidere/src/main/res/drawable/image_preview_refresh.xml index bb50968bc..8e6dc420d 100644 --- a/twidere/src/main/res/drawable/image_preview_refresh.xml +++ b/twidere/src/main/res/drawable/image_preview_refresh.xml @@ -1,7 +1,7 @@ + android:antialias="true" + android:dither="true" + android:gravity="center" + android:src="@drawable/image_preview_refresh_bitmap" + android:tileMode="disabled"/> diff --git a/twidere/src/main/res/drawable/nyan_sakamoto.xml b/twidere/src/main/res/drawable/nyan_sakamoto.xml deleted file mode 100644 index 1773f57bf..000000000 --- a/twidere/src/main/res/drawable/nyan_sakamoto.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/drawable/nyan_sakamoto_santa.xml b/twidere/src/main/res/drawable/nyan_sakamoto_santa.xml deleted file mode 100644 index 8b84eed7b..000000000 --- a/twidere/src/main/res/drawable/nyan_sakamoto_santa.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/drawable/nyan_sakamoto_thumbnail.xml b/twidere/src/main/res/drawable/nyan_sakamoto_thumbnail.xml index 0b89d80a6..a073c2e27 100644 --- a/twidere/src/main/res/drawable/nyan_sakamoto_thumbnail.xml +++ b/twidere/src/main/res/drawable/nyan_sakamoto_thumbnail.xml @@ -1,6 +1,6 @@ + android:antialias="true" + android:filter="true" + android:src="@drawable/nyan_sakamoto_thumbnail_bitmap" + android:tileMode="disabled"/> diff --git a/twidere/src/main/res/drawable/nyan_stars_background.xml b/twidere/src/main/res/drawable/nyan_stars_background.xml index c4d49d4ae..f9003dbec 100644 --- a/twidere/src/main/res/drawable/nyan_stars_background.xml +++ b/twidere/src/main/res/drawable/nyan_stars_background.xml @@ -1,6 +1,6 @@ + android:antialias="false" + android:filter="false" + android:src="@drawable/nyan_stars_background_tile" + android:tileMode="repeat"/> diff --git a/twidere/src/main/res/drawable/shadow_bottom.xml b/twidere/src/main/res/drawable/shadow_bottom.xml index 1bb666624..bda08cadd 100644 --- a/twidere/src/main/res/drawable/shadow_bottom.xml +++ b/twidere/src/main/res/drawable/shadow_bottom.xml @@ -1,10 +1,10 @@ - + android:centerColor="#11000000" + android:endColor="#00000000" + android:startColor="#33000000"/> \ No newline at end of file diff --git a/twidere/src/main/res/drawable/shadow_left.xml b/twidere/src/main/res/drawable/shadow_left.xml index d1aebf3e9..7a221f326 100644 --- a/twidere/src/main/res/drawable/shadow_left.xml +++ b/twidere/src/main/res/drawable/shadow_left.xml @@ -1,9 +1,9 @@ - + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/shadow_right.xml b/twidere/src/main/res/drawable/shadow_right.xml index 5472424ef..bc1291e19 100644 --- a/twidere/src/main/res/drawable/shadow_right.xml +++ b/twidere/src/main/res/drawable/shadow_right.xml @@ -1,9 +1,9 @@ - + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/shadow_top.xml b/twidere/src/main/res/drawable/shadow_top.xml index 6a8f8e3f3..8c4db8c02 100644 --- a/twidere/src/main/res/drawable/shadow_top.xml +++ b/twidere/src/main/res/drawable/shadow_top.xml @@ -1,10 +1,10 @@ - + \ No newline at end of file diff --git a/twidere/src/main/res/drawable/shadow_user_banner_action_bar.xml b/twidere/src/main/res/drawable/shadow_user_banner_action_bar.xml index 38cb634c2..344ba221e 100644 --- a/twidere/src/main/res/drawable/shadow_user_banner_action_bar.xml +++ b/twidere/src/main/res/drawable/shadow_user_banner_action_bar.xml @@ -4,7 +4,7 @@ + android:startColor="#A0000000" + android:type="linear"/> \ No newline at end of file diff --git a/twidere/src/main/res/drawable/shadow_user_banner_image.xml b/twidere/src/main/res/drawable/shadow_user_banner_image.xml index f2e482de7..1288523ab 100644 --- a/twidere/src/main/res/drawable/shadow_user_banner_image.xml +++ b/twidere/src/main/res/drawable/shadow_user_banner_image.xml @@ -3,8 +3,8 @@ \ No newline at end of file diff --git a/twidere/src/main/res/layout-v21/layout_home_actions_button.xml b/twidere/src/main/res/layout-v21/layout_home_actions_button.xml index 64535c63d..8a6c7b402 100644 --- a/twidere/src/main/res/layout-v21/layout_home_actions_button.xml +++ b/twidere/src/main/res/layout-v21/layout_home_actions_button.xml @@ -1,4 +1,23 @@ + + . --> - + diff --git a/twidere/src/main/res/layout/action_item_compose_account.xml b/twidere/src/main/res/layout/action_item_compose_account.xml index e1d68bfca..ea176c251 100644 --- a/twidere/src/main/res/layout/action_item_compose_account.xml +++ b/twidere/src/main/res/layout/action_item_compose_account.xml @@ -1,4 +1,23 @@ + + + + + + + + - + - + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/action_item_messages_conversation_profile_image.xml b/twidere/src/main/res/layout/action_item_messages_conversation_profile_image.xml index bea72c939..89d6b06f3 100644 --- a/twidere/src/main/res/layout/action_item_messages_conversation_profile_image.xml +++ b/twidere/src/main/res/layout/action_item_messages_conversation_profile_image.xml @@ -30,6 +30,7 @@ - + - + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout/actionbar_custom_view_done_cancel.xml b/twidere/src/main/res/layout/actionbar_custom_view_done_cancel.xml index 1a6e5141e..52ee130ac 100644 --- a/twidere/src/main/res/layout/actionbar_custom_view_done_cancel.xml +++ b/twidere/src/main/res/layout/actionbar_custom_view_done_cancel.xml @@ -1,3 +1,4 @@ + - - - + + + diff --git a/twidere/src/main/res/layout/activity_account_selector.xml b/twidere/src/main/res/layout/activity_account_selector.xml index 57b8ea657..30e5a51c1 100644 --- a/twidere/src/main/res/layout/activity_account_selector.xml +++ b/twidere/src/main/res/layout/activity_account_selector.xml @@ -1,39 +1,59 @@ - + - + - + - + -