mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-17 04:00:48 +01:00
migrating to kotlin
This commit is contained in:
parent
ad612d5a5b
commit
23494b009f
@ -3,6 +3,7 @@ package org.mariotaku.twidere.model;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
@ -20,6 +21,7 @@ public class ParcelableMediaUpdate implements Parcelable {
|
||||
public int type;
|
||||
|
||||
@JsonField(name = "alt_text")
|
||||
@Nullable
|
||||
public String alt_text;
|
||||
|
||||
public ParcelableMediaUpdate() {
|
||||
|
@ -10,7 +10,7 @@ apply plugin: 'io.fabric'
|
||||
// END Non-FOSS component
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.0.2-1'
|
||||
ext.kotlin_version = '1.0.3'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
|
@ -1,38 +1,37 @@
|
||||
package org.mariotaku.twidere.activity;
|
||||
package org.mariotaku.twidere.activity
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import android.net.Uri
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/3.
|
||||
*/
|
||||
public class ImagePageFragmentTest {
|
||||
class ImagePageFragmentTest {
|
||||
|
||||
@Test
|
||||
public void testReplaceTwitterMediaUri() throws Exception {
|
||||
@Throws(Exception::class)
|
||||
fun testReplaceTwitterMediaUri() {
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png:large",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.png:large")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.png:large")).toString())
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png:orig",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.png:orig")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.png:orig")).toString())
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png:large",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:large")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:large")).toString())
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png:large",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:orig")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:orig")).toString())
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg")).toString())
|
||||
assertEquals("https://pbs.twimg.com/media/DEADBEEF.png:",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:")).toString());
|
||||
"https://pbs.twimg.com/media/DEADBEEF.jpg:")).toString())
|
||||
assertEquals("https://example.com/media/DEADBEEF.jpg",
|
||||
MediaViewerActivity.ImagePageFragment.replaceTwitterMediaUri(Uri.parse(
|
||||
"https://example.com/media/DEADBEEF.jpg")).toString());
|
||||
"https://example.com/media/DEADBEEF.jpg")).toString())
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/9.
|
||||
*/
|
||||
public class UserKeyTest {
|
||||
|
||||
@Test
|
||||
public void testToString() throws Exception {
|
||||
assertEquals("abc@twitter.com", new UserKey("abc", "twitter.com").toString());
|
||||
assertEquals("\\@user@twitter.com", new UserKey("@user", "twitter.com").toString());
|
||||
assertEquals("\\@u\\\\ser@twitter.com", new UserKey("@u\\ser", "twitter.com").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOf() throws Exception {
|
||||
assertEquals(new UserKey("abc", "twitter.com"), UserKey.valueOf("abc@twitter.com"));
|
||||
assertEquals(new UserKey("abc@", "twitter.com"), UserKey.valueOf("abc\\@@twitter.com"));
|
||||
assertEquals(new UserKey("abc@", "twitter.com"), UserKey.valueOf("a\\bc\\@@twitter.com"));
|
||||
assertEquals(new UserKey("a\\bc@", "twitter.com"), UserKey.valueOf("a\\\\bc\\@@twitter.com"));
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.mariotaku.twidere.model
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/9.
|
||||
*/
|
||||
class UserKeyTest {
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testToString() {
|
||||
assertEquals("abc@twitter.com", UserKey("abc", "twitter.com").toString())
|
||||
assertEquals("\\@user@twitter.com", UserKey("@user", "twitter.com").toString())
|
||||
assertEquals("\\@u\\\\ser@twitter.com", UserKey("@u\\ser", "twitter.com").toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testValueOf() {
|
||||
assertEquals(UserKey("abc", "twitter.com"), UserKey.valueOf("abc@twitter.com"))
|
||||
assertEquals(UserKey("abc@", "twitter.com"), UserKey.valueOf("abc\\@@twitter.com"))
|
||||
assertEquals(UserKey("abc@", "twitter.com"), UserKey.valueOf("a\\bc\\@@twitter.com"))
|
||||
assertEquals(UserKey("a\\bc@", "twitter.com"), UserKey.valueOf("a\\\\bc\\@@twitter.com"))
|
||||
}
|
||||
}
|
@ -1,24 +1,24 @@
|
||||
package org.mariotaku.twidere.task;
|
||||
package org.mariotaku.twidere.task
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/2.
|
||||
*/
|
||||
public class SaveFileTaskTest {
|
||||
class SaveFileTaskTest {
|
||||
|
||||
@Test
|
||||
public void testGetFileNameWithExtension() throws Exception {
|
||||
@Throws(Exception::class)
|
||||
fun testGetFileNameWithExtension() {
|
||||
assertEquals("pbs_twimg_com_media_abcdefghijklmn.jpg",
|
||||
SaveFileTask.getFileNameWithExtension("pbs_twimg_com_media_abcdefghijklmn_jpg",
|
||||
"jpg", '_', null));
|
||||
"jpg", '_', null))
|
||||
assertEquals("pbs_twimg_com_media_abcdefghijklmn_jpg",
|
||||
SaveFileTask.getFileNameWithExtension("pbs_twimg_com_media_abcdefghijklmn_jpg",
|
||||
null, '_', null));
|
||||
null, '_', null))
|
||||
assertEquals("pbs_twimg_com_media_abcdefghijklmn_jpgsuffix",
|
||||
SaveFileTask.getFileNameWithExtension("pbs_twimg_com_media_abcdefghijklmn_jpg",
|
||||
null, '_', "suffix"));
|
||||
null, '_', "suffix"))
|
||||
}
|
||||
}
|
@ -1,30 +1,31 @@
|
||||
package org.mariotaku.twidere.util;
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.Test
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/10.
|
||||
*/
|
||||
public class MicroBlogAPIFactoryTest {
|
||||
class MicroBlogAPIFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testGetApiUrl() throws Exception {
|
||||
assertEquals("https://api.twitter.com/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", null));
|
||||
assertEquals("https://api.twitter.com/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", null));
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1/"));
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "1.1"));
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1"));
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "/1.1"));
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "1.1/"));
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "1.1/"));
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1/"));
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "/1.1/"));
|
||||
@Throws(Exception::class)
|
||||
fun testGetApiUrl() {
|
||||
assertEquals("https://api.twitter.com/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", null))
|
||||
assertEquals("https://api.twitter.com/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", null))
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1/"))
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "1.1"))
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1"))
|
||||
assertEquals("https://api.twitter.com/1.1", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "/1.1"))
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "1.1/"))
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "1.1/"))
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com", "api", "/1.1/"))
|
||||
assertEquals("https://api.twitter.com/1.1/", MicroBlogAPIFactory.getApiUrl("https://[DOMAIN.]twitter.com/", "api", "/1.1/"))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApiBaseUrl() {
|
||||
assertEquals("https://media.twitter.com", MicroBlogAPIFactory.getApiBaseUrl("https://api.twitter.com", "media"));
|
||||
fun testGetApiBaseUrl() {
|
||||
assertEquals("https://media.twitter.com", MicroBlogAPIFactory.getApiBaseUrl("https://api.twitter.com", "media"))
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/31.
|
||||
*/
|
||||
public class TwidereArrayUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testMergeArray() throws Exception {
|
||||
String[] array1 = {"1", "2"};
|
||||
String[] array2 = {"1", "2"};
|
||||
String[] array3 = null;
|
||||
|
||||
//noinspection ConstantConditions
|
||||
String[] merged = new String[TwidereArrayUtils.arraysLength(array1, array2, array3)];
|
||||
//noinspection ConstantConditions
|
||||
TwidereArrayUtils.mergeArray(merged, array1, array2, array3);
|
||||
String[] expected = {"1", "2", "1", "2"};
|
||||
assertArrayEquals(expected, merged);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArraysLength() throws Exception {
|
||||
String[] array1 = {"1", "2"};
|
||||
String[] array2 = {"1", "2"};
|
||||
String[] array3 = null;
|
||||
//noinspection ConstantConditions
|
||||
assertEquals(4, TwidereArrayUtils.arraysLength(array1, array2, array3));
|
||||
assertEquals(6, TwidereArrayUtils.arraysLength(array1, array2, array2));
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import junit.framework.Assert.assertEquals
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/31.
|
||||
*/
|
||||
class TwidereArrayUtilsTest {
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testMergeArray() {
|
||||
val array1 = arrayOf("1", "2")
|
||||
val array2 = arrayOf("1", "2")
|
||||
val array3: Array<String>? = null
|
||||
|
||||
//noinspection ConstantConditions
|
||||
val merged = arrayOfNulls<String>(TwidereArrayUtils.arraysLength(array1, array2, array3))
|
||||
//noinspection ConstantConditions
|
||||
TwidereArrayUtils.mergeArray(merged, array1, array2, array3)
|
||||
val expected = arrayOf("1", "2", "1", "2")
|
||||
assertArrayEquals(expected, merged)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testArraysLength() {
|
||||
val array1 = arrayOf("1", "2")
|
||||
val array2 = arrayOf("1", "2")
|
||||
val array3: Array<String>? = null
|
||||
//noinspection ConstantConditions
|
||||
assertEquals(4, TwidereArrayUtils.arraysLength(array1, array2, array3))
|
||||
assertEquals(6, TwidereArrayUtils.arraysLength(array1, array2, array2))
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/23.
|
||||
*/
|
||||
public class TwidereMathUtilsTest {
|
||||
|
||||
public void testClamp() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testClamp1() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testNextPowerOf2() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testPrevPowerOf2() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testSum() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testSum1() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testSum2() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInRange() {
|
||||
assertTrue(TwidereMathUtils.inRange(5, 0, 10, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(0, 0, 10, TwidereMathUtils.RANGE_EXCLUSIVE_EXCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(0, 5, 10, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(5, 5, 10, TwidereMathUtils.RANGE_EXCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(10, 5, 10, TwidereMathUtils.RANGE_INCLUSIVE_EXCLUSIVE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInRange1() {
|
||||
assertTrue(TwidereMathUtils.inRange(5f, 0f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(0f, 0f, 10f, TwidereMathUtils.RANGE_EXCLUSIVE_EXCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(0f, 5f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(5f, 5f, 10f, TwidereMathUtils.RANGE_EXCLUSIVE_INCLUSIVE));
|
||||
assertFalse(TwidereMathUtils.inRange(10f, 5f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_EXCLUSIVE));
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/1/23.
|
||||
*/
|
||||
class TwidereMathUtilsTest {
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testClamp() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testClamp1() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testNextPowerOf2() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testPrevPowerOf2() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testSum() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testSum1() {
|
||||
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testSum2() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInRange() {
|
||||
assertTrue(TwidereMathUtils.inRange(5, 0, 10, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(0, 0, 10, TwidereMathUtils.RANGE_EXCLUSIVE_EXCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(0, 5, 10, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(5, 5, 10, TwidereMathUtils.RANGE_EXCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(10, 5, 10, TwidereMathUtils.RANGE_INCLUSIVE_EXCLUSIVE))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInRange1() {
|
||||
assertTrue(TwidereMathUtils.inRange(5f, 0f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(0f, 0f, 10f, TwidereMathUtils.RANGE_EXCLUSIVE_EXCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(0f, 5f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(5f, 5f, 10f, TwidereMathUtils.RANGE_EXCLUSIVE_INCLUSIVE))
|
||||
assertFalse(TwidereMathUtils.inRange(10f, 5f, 10f, TwidereMathUtils.RANGE_INCLUSIVE_EXCLUSIVE))
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import org.apache.commons.lang3.reflect.TypeUtils;
|
||||
import org.junit.Test;
|
||||
import org.mariotaku.microblog.library.twitter.model.CursorTimestampResponse;
|
||||
import org.mariotaku.microblog.library.twitter.model.ResponseList;
|
||||
import org.mariotaku.microblog.library.twitter.model.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/15.
|
||||
*/
|
||||
public class TwidereTypeUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetSimpleName() throws Exception {
|
||||
assertEquals("CursorTimestampResponse", TwidereTypeUtils.toSimpleName(CursorTimestampResponse.class));
|
||||
assertEquals("ResponseList<Status>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(ResponseList.class, Status.class)));
|
||||
assertEquals("List<List<Object>>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(List.class, TypeUtils.parameterize(List.class, Object.class))));
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import org.apache.commons.lang3.reflect.TypeUtils
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mariotaku.microblog.library.twitter.model.CursorTimestampResponse
|
||||
import org.mariotaku.microblog.library.twitter.model.ResponseList
|
||||
import org.mariotaku.microblog.library.twitter.model.Status
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/15.
|
||||
*/
|
||||
class TwidereTypeUtilsTest {
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testGetSimpleName() {
|
||||
assertEquals("CursorTimestampResponse", TwidereTypeUtils.toSimpleName(CursorTimestampResponse::class.java))
|
||||
assertEquals("ResponseList<Status>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(ResponseList::class.java, Status::class.java)))
|
||||
assertEquals("List<List<Object>>", TwidereTypeUtils.toSimpleName(TypeUtils.parameterize(List::class.java, TypeUtils.parameterize(List::class.java, Any::class.java))))
|
||||
}
|
||||
}
|
@ -1,33 +1,35 @@
|
||||
package org.mariotaku.twidere.util;
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.Test
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import junit.framework.Assert.assertEquals
|
||||
import junit.framework.Assert.assertNull
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/9.
|
||||
*/
|
||||
public class UriUtilsTest {
|
||||
class UriUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetAuthority() throws Exception {
|
||||
assertEquals("www.google.com", UriUtils.getAuthority("http://www.google.com/"));
|
||||
assertEquals("twitter.com", UriUtils.getAuthority("https://twitter.com"));
|
||||
assertNull(UriUtils.getAuthority("www.google.com/"));
|
||||
@Throws(Exception::class)
|
||||
fun testGetAuthority() {
|
||||
assertEquals("www.google.com", UriUtils.getAuthority("http://www.google.com/"))
|
||||
assertEquals("twitter.com", UriUtils.getAuthority("https://twitter.com"))
|
||||
assertNull(UriUtils.getAuthority("www.google.com/"))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPath() throws Exception {
|
||||
assertEquals("/", UriUtils.getPath("http://www.example.com/"));
|
||||
assertEquals("", UriUtils.getPath("http://www.example.com"));
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path"));
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path?with=query"));
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/?with=query"));
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path?with=query#fragment"));
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/?with=query#fragment"));
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path#fragment"));
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/#fragment"));
|
||||
@Throws(Exception::class)
|
||||
fun testGetPath() {
|
||||
assertEquals("/", UriUtils.getPath("http://www.example.com/"))
|
||||
assertEquals("", UriUtils.getPath("http://www.example.com"))
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path"))
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path?with=query"))
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/?with=query"))
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path?with=query#fragment"))
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/?with=query#fragment"))
|
||||
assertEquals("/test/path", UriUtils.getPath("https://example.com/test/path#fragment"))
|
||||
assertEquals("/test/path/", UriUtils.getPath("https://example.com/test/path/#fragment"))
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package org.mariotaku.twidere.util.media.preview.provider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/20.
|
||||
*/
|
||||
public class InstagramProviderTest {
|
||||
|
||||
final InstagramProvider provider = new InstagramProvider();
|
||||
|
||||
@Test
|
||||
public void testFrom() throws Exception {
|
||||
ParcelableMedia media = provider.from("https://www.instagram.com/p/abcd1234");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234?key=value");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/?key=value");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/?key=value#fragment");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234#fragment");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/#fragment");
|
||||
assertNotNull(media);
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media.media_url);
|
||||
media = provider.from("https://www.instagram.com/user");
|
||||
assertNull(media);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package org.mariotaku.twidere.util.media.preview.provider
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.mariotaku.twidere.model.ParcelableMedia
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/20.
|
||||
*/
|
||||
class InstagramProviderTest {
|
||||
|
||||
internal val provider = InstagramProvider()
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testFrom() {
|
||||
var media: ParcelableMedia ? = provider.from("https://www.instagram.com/p/abcd1234")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234?key=value")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/?key=value")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/?key=value#fragment")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234#fragment")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/p/abcd1234/#fragment")
|
||||
assertEquals("https://instagram.com/p/abcd1234/media/?size=l", media!!.media_url)
|
||||
media = provider.from("https://www.instagram.com/user")
|
||||
assertNull(media)
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
|
||||
public class AssistLauncherActivity extends Activity implements Constants {
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(this, SHARED_PREFERENCES_NAME,
|
||||
MODE_PRIVATE);
|
||||
final String composeNowAction = prefs.getString(KEY_COMPOSE_NOW_ACTION, VALUE_COMPOSE_NOW_ACTION_COMPOSE), action;
|
||||
if (VALUE_COMPOSE_NOW_ACTION_TAKE_PHOTO.equals(composeNowAction)) {
|
||||
action = INTENT_ACTION_COMPOSE_TAKE_PHOTO;
|
||||
} else if (VALUE_COMPOSE_NOW_ACTION_PICK_IMAGE.equals(composeNowAction)) {
|
||||
action = INTENT_ACTION_COMPOSE_PICK_IMAGE;
|
||||
} else {
|
||||
action = INTENT_ACTION_COMPOSE;
|
||||
}
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
intent.setClass(this, ComposeActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
@ -1,437 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback;
|
||||
import android.support.v7.view.menu.ActionMenuItemView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.support.v7.widget.TwidereActionMenuView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
|
||||
import com.afollestad.appthemeengine.ATE;
|
||||
import com.afollestad.appthemeengine.ATEActivity;
|
||||
import com.afollestad.appthemeengine.Config;
|
||||
import com.afollestad.appthemeengine.customizers.ATEStatusBarCustomizer;
|
||||
import com.afollestad.appthemeengine.customizers.ATEToolbarCustomizer;
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.activity.iface.IAppCompatActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.preference.iface.IDialogPreference;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.NotificationManagerWrapper;
|
||||
import org.mariotaku.twidere.util.PermissionsManager;
|
||||
import org.mariotaku.twidere.util.ReadStateManager;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.StrictModeUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@SuppressLint("Registered")
|
||||
public class BaseActivity extends ATEActivity implements Constants, IExtendedActivity,
|
||||
IThemedActivity, IAppCompatActivity, IControlBarActivity, OnFitSystemWindowsListener,
|
||||
SystemWindowsInsetsCallback, KeyboardShortcutCallback, OnPreferenceDisplayDialogCallback,
|
||||
ATEToolbarCustomizer, ATEStatusBarCustomizer {
|
||||
|
||||
private static final String[] sClassPrefixList = {
|
||||
"android.widget.",
|
||||
"android.view.",
|
||||
"android.webkit."
|
||||
};
|
||||
// Utility classes
|
||||
@Inject
|
||||
protected KeyboardShortcutsHandler mKeyboardShortcutsHandler;
|
||||
@Inject
|
||||
protected AsyncTwitterWrapper mTwitterWrapper;
|
||||
@Inject
|
||||
protected ReadStateManager mReadStateManager;
|
||||
@Inject
|
||||
protected Bus mBus;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
protected NotificationManagerWrapper mNotificationManager;
|
||||
@Inject
|
||||
protected MediaLoaderWrapper mMediaLoader;
|
||||
@Inject
|
||||
protected UserColorNameManager mUserColorNameManager;
|
||||
@Inject
|
||||
protected PermissionsManager mPermissionsManager;
|
||||
|
||||
private ActionHelper mActionHelper = new ActionHelper(this);
|
||||
|
||||
// Registered listeners
|
||||
private ArrayList<ControlBarOffsetListener> mControlBarOffsetListeners = new ArrayList<>();
|
||||
|
||||
// Data fields
|
||||
private Rect mSystemWindowsInsets;
|
||||
private int mKeyMetaState;
|
||||
// Data fields
|
||||
private int mCurrentThemeBackgroundAlpha;
|
||||
private String mCurrentThemeBackgroundOption;
|
||||
|
||||
@Override
|
||||
public boolean getSystemWindowsInsets(Rect insets) {
|
||||
if (mSystemWindowsInsets == null) return false;
|
||||
insets.set(mSystemWindowsInsets);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFitSystemWindows(Rect insets) {
|
||||
if (mSystemWindowsInsets == null)
|
||||
mSystemWindowsInsets = new Rect(insets);
|
||||
else {
|
||||
mSystemWindowsInsets.set(insets);
|
||||
}
|
||||
notifyControlBarOffsetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
final int keyCode = event.getKeyCode();
|
||||
if (KeyEvent.isModifierKey(keyCode)) {
|
||||
final int action = event.getAction();
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mKeyMetaState |= KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode);
|
||||
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||
mKeyMetaState &= ~KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode);
|
||||
}
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
|
||||
if (handleKeyboardShortcutSingle(mKeyboardShortcutsHandler, keyCode, event, mKeyMetaState))
|
||||
return true;
|
||||
return isKeyboardShortcutHandled(mKeyboardShortcutsHandler, keyCode, event, mKeyMetaState) || super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (handleKeyboardShortcutRepeat(mKeyboardShortcutsHandler, keyCode, event.getRepeatCount(), event, mKeyMetaState))
|
||||
return true;
|
||||
return isKeyboardShortcutHandled(mKeyboardShortcutsHandler, keyCode, event, mKeyMetaState) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyboardShortcutHandled(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event, int metaState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictModeUtils.detectAllVmPolicy();
|
||||
StrictModeUtils.detectAllThreadPolicy();
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
GeneralComponentHelper.build(this).inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
|
||||
if (adapter != null && adapter.isEnabled()) {
|
||||
|
||||
final IntentFilter handlerFilter = IntentUtils.getWebLinkIntentFilter(this);
|
||||
if (handlerFilter != null) {
|
||||
final Intent linkIntent = new Intent(this, WebLinkHandlerActivity.class);
|
||||
final PendingIntent intent = PendingIntent.getActivity(this, 0, linkIntent, 0);
|
||||
final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
||||
for (int i = 0, j = handlerFilter.countDataSchemes(); i < j; i++) {
|
||||
intentFilter.addDataScheme(handlerFilter.getDataScheme(i));
|
||||
}
|
||||
for (int i = 0, j = handlerFilter.countDataAuthorities(); i < j; i++) {
|
||||
final IntentFilter.AuthorityEntry authorityEntry = handlerFilter.getDataAuthority(i);
|
||||
final int port = authorityEntry.getPort();
|
||||
intentFilter.addDataAuthority(authorityEntry.getHost(), port < 0 ? null : Integer.toString(port));
|
||||
}
|
||||
try {
|
||||
adapter.enableForegroundDispatch(this, intent, new IntentFilter[]{intentFilter}, null);
|
||||
} catch (Exception e) {
|
||||
// Ignore if blocked by modified roms
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
|
||||
if (adapter != null && adapter.isEnabled()) {
|
||||
try {
|
||||
adapter.disableForegroundDispatch(this);
|
||||
} catch (Exception e) {
|
||||
// Ignore if blocked by modified roms
|
||||
}
|
||||
}
|
||||
mActionHelper.dispatchOnPause();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlBarOffset(float offset) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlBarVisibleAnimate(boolean visible) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlBarVisibleAnimate(boolean visible, ControlBarShowHideHelper.ControlBarAnimationListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getControlBarOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlBarHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyControlBarOffsetChanged() {
|
||||
final float offset = getControlBarOffset();
|
||||
for (final ControlBarOffsetListener l : mControlBarOffsetListeners) {
|
||||
l.onControlBarOffsetChanged(this, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerControlBarOffsetListener(ControlBarOffsetListener listener) {
|
||||
mControlBarOffsetListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterControlBarOffsetListener(ControlBarOffsetListener listener) {
|
||||
mControlBarOffsetListeners.remove(listener);
|
||||
}
|
||||
|
||||
public int getKeyMetaState() {
|
||||
return mKeyMetaState;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
mActionHelper.dispatchOnResumeFragments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAfterFragmentResumed(Action action) {
|
||||
mActionHelper.executeAfterFragmentResumed(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentThemeBackgroundAlpha() {
|
||||
return mCurrentThemeBackgroundAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentThemeBackgroundOption() {
|
||||
return mCurrentThemeBackgroundOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeBackgroundAlpha() {
|
||||
return ThemeUtils.getUserThemeBackgroundAlpha(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThemeBackgroundOption() {
|
||||
return ThemeUtils.getThemeBackgroundOption(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getATEKey() {
|
||||
return ThemeUtils.getATEKey(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyThemeResource(@NonNull Resources.Theme theme, int resId, boolean first) {
|
||||
mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha();
|
||||
mCurrentThemeBackgroundOption = getThemeBackgroundOption();
|
||||
super.onApplyThemeResource(theme, resId, first);
|
||||
final Window window = getWindow();
|
||||
if (window != null && shouldApplyWindowBackground()) {
|
||||
ThemeUtils.applyWindowBackground(this, window, getThemeBackgroundOption(),
|
||||
getThemeBackgroundAlpha());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
ThemeUtils.fixNightMode(getResources(), newConfig);
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
protected boolean shouldApplyWindowBackground() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
|
||||
// Fix for https://github.com/afollestad/app-theme-engine/issues/109
|
||||
if (context != this) {
|
||||
final AppCompatDelegate delegate = getDelegate();
|
||||
View view = delegate.createView(parent, name, context, attrs);
|
||||
if (view == null) {
|
||||
view = newInstance(name, context, attrs);
|
||||
}
|
||||
if (view == null) {
|
||||
view = newInstance(name, context, attrs);
|
||||
}
|
||||
if (view != null) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
if (parent instanceof TwidereActionMenuView) {
|
||||
final Class<?> cls = findClass(name);
|
||||
if (cls != null && ActionMenuItemView.class.isAssignableFrom(cls)) {
|
||||
return ((TwidereActionMenuView) parent).createActionMenuView(context, attrs);
|
||||
}
|
||||
}
|
||||
return super.onCreateView(parent, name, context, attrs);
|
||||
}
|
||||
|
||||
private Class<?> findClass(String name) {
|
||||
Class<?> cls = null;
|
||||
try {
|
||||
cls = Class.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Ignore
|
||||
}
|
||||
if (cls != null) return cls;
|
||||
for (String prefix : sClassPrefixList) {
|
||||
try {
|
||||
cls = Class.forName(prefix + name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Ignore
|
||||
}
|
||||
if (cls != null) return cls;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private View newInstance(String name, Context context, AttributeSet attrs) {
|
||||
try {
|
||||
final Class<?> cls = findClass(name);
|
||||
if (cls == null) throw new ClassNotFoundException(name);
|
||||
final Constructor<?> constructor = cls.getConstructor(Context.class, AttributeSet.class);
|
||||
return (View) constructor.newInstance(context, attrs);
|
||||
} catch (InstantiationException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
} catch (InvocationTargetException e) {
|
||||
return null;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceDisplayDialog(PreferenceFragmentCompat fragment, Preference preference) {
|
||||
if (preference instanceof IDialogPreference) {
|
||||
((IDialogPreference) preference).displayDialog(fragment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusBarColor() {
|
||||
return ATE.USE_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getToolbarColor(@Nullable Toolbar toolbar) {
|
||||
return ATE.USE_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightStatusBarMode() {
|
||||
//noinspection WrongConstant
|
||||
return ThemeUtils.getLightStatusBarMode(Config.statusBarColor(this, getATEKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightToolbarMode(@Nullable Toolbar toolbar) {
|
||||
//noinspection WrongConstant
|
||||
return ThemeUtils.getLightToolbarMode(Config.toolbarColor(this, getATEKey(), toolbar));
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -241,18 +241,18 @@ public class CustomTabEditorActivity extends BaseActivity implements OnClickList
|
||||
icon.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
|
||||
if (value instanceof ParcelableUser) {
|
||||
final ParcelableUser user = (ParcelableUser) value;
|
||||
text1.setText(mUserColorNameManager.getUserNickname(user.key, user.name));
|
||||
text1.setText(userColorNameManager.getUserNickname(user.key, user.name));
|
||||
text2.setText(String.format("@%s", user.screen_name));
|
||||
if (displayProfileImage) {
|
||||
mMediaLoader.displayProfileImage(icon, user);
|
||||
mediaLoader.displayProfileImage(icon, user);
|
||||
}
|
||||
} else if (value instanceof ParcelableUserList) {
|
||||
final ParcelableUserList userList = (ParcelableUserList) value;
|
||||
final String createdBy = mUserColorNameManager.getDisplayName(userList, displayName);
|
||||
final String createdBy = userColorNameManager.getDisplayName(userList, displayName);
|
||||
text1.setText(userList.name);
|
||||
text2.setText(getString(R.string.created_by, createdBy));
|
||||
if (displayProfileImage) {
|
||||
mMediaLoader.displayProfileImage(icon, userList.user_profile_image_url);
|
||||
mediaLoader.displayProfileImage(icon, userList.user_profile_image_url);
|
||||
}
|
||||
} else if (value instanceof CharSequence) {
|
||||
text2.setVisibility(View.GONE);
|
||||
|
@ -1,155 +0,0 @@
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
import org.mariotaku.twidere.util.DataImportExportUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DataExportActivity extends BaseActivity implements
|
||||
DataExportImportTypeSelectorDialogFragment.Callback {
|
||||
|
||||
private ExportSettingsTask mTask;
|
||||
private Runnable mResumeFragmentsRunnable;
|
||||
|
||||
@Override
|
||||
public void onCancelled(DialogFragment df) {
|
||||
if (!isFinishing()) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed(final DialogFragment df) {
|
||||
if (df instanceof DataExportImportTypeSelectorDialogFragment) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
if (mResumeFragmentsRunnable != null) {
|
||||
mResumeFragmentsRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_PICK_DIRECTORY: {
|
||||
mResumeFragmentsRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (resultCode == RESULT_OK) {
|
||||
final String path = data.getData().getPath();
|
||||
final DialogFragment df = new DataExportImportTypeSelectorDialogFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(EXTRA_PATH, path);
|
||||
args.putString(EXTRA_TITLE, getString(R.string.export_settings_type_dialog_title));
|
||||
df.setArguments(args);
|
||||
df.show(getSupportFragmentManager(), "select_export_type");
|
||||
} else {
|
||||
if (!isFinishing()) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositiveButtonClicked(final String path, final int flags) {
|
||||
if (path == null || flags == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (mTask == null || mTask.getStatus() != AsyncTask.Status.RUNNING) {
|
||||
mTask = new ExportSettingsTask(this, path, flags);
|
||||
mTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState == null) {
|
||||
final Intent intent = new Intent(this, FileSelectorActivity.class);
|
||||
intent.setAction(INTENT_ACTION_PICK_DIRECTORY);
|
||||
startActivityForResult(intent, REQUEST_PICK_DIRECTORY);
|
||||
}
|
||||
}
|
||||
|
||||
static class ExportSettingsTask extends AsyncTask<Object, Object, Boolean> {
|
||||
private static final String FRAGMENT_TAG = "import_settings_dialog";
|
||||
|
||||
private final DataExportActivity mActivity;
|
||||
private final String mPath;
|
||||
private final int mFlags;
|
||||
|
||||
ExportSettingsTask(final DataExportActivity activity, final String path, final int flags) {
|
||||
mActivity = activity;
|
||||
mPath = path;
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(final Object... params) {
|
||||
if (mPath == null) return false;
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US);
|
||||
final String fileName = String.format("Twidere_Settings_%s.zip", sdf.format(new Date()));
|
||||
final File file = new File(mPath, fileName);
|
||||
file.delete();
|
||||
try {
|
||||
DataImportExportUtils.exportData(mActivity, file, mFlags);
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
final FragmentManager fm = mActivity.getSupportFragmentManager();
|
||||
final DialogFragment f = (DialogFragment) fm.findFragmentByTag(FRAGMENT_TAG);
|
||||
if (f != null) {
|
||||
f.dismiss();
|
||||
}
|
||||
if (result != null && result) {
|
||||
mActivity.setResult(RESULT_OK);
|
||||
} else {
|
||||
mActivity.setResult(RESULT_CANCELED);
|
||||
}
|
||||
mActivity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
ProgressDialogFragment.show(mActivity, FRAGMENT_TAG).setCancelable(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
import org.mariotaku.twidere.util.DataImportExportUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DataImportActivity extends BaseActivity implements
|
||||
DataExportImportTypeSelectorDialogFragment.Callback {
|
||||
|
||||
private ImportSettingsTask mImportSettingsTask;
|
||||
private OpenImportTypeTask mOpenImportTypeTask;
|
||||
private Runnable mResumeFragmentsRunnable;
|
||||
|
||||
@Override
|
||||
public void onCancelled(final DialogFragment df) {
|
||||
if (!isFinishing()) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed(final DialogFragment df) {
|
||||
if (df instanceof DataExportImportTypeSelectorDialogFragment) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_PICK_FILE: {
|
||||
mResumeFragmentsRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (resultCode == RESULT_OK) {
|
||||
final String path = data.getData().getPath();
|
||||
if (mOpenImportTypeTask == null || mOpenImportTypeTask.getStatus() != AsyncTask.Status.RUNNING) {
|
||||
mOpenImportTypeTask = new OpenImportTypeTask(DataImportActivity.this, path);
|
||||
mOpenImportTypeTask.execute();
|
||||
}
|
||||
} else {
|
||||
if (!isFinishing()) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
if (mResumeFragmentsRunnable != null) {
|
||||
mResumeFragmentsRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositiveButtonClicked(final String path, final int flags) {
|
||||
if (path == null || flags == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (mImportSettingsTask == null || mImportSettingsTask.getStatus() != AsyncTask.Status.RUNNING) {
|
||||
mImportSettingsTask = new ImportSettingsTask(this, path, flags);
|
||||
mImportSettingsTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState == null) {
|
||||
final Intent intent = new Intent(this, FileSelectorActivity.class);
|
||||
intent.setAction(INTENT_ACTION_PICK_FILE);
|
||||
startActivityForResult(intent, REQUEST_PICK_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
static class ImportSettingsTask extends AsyncTask<Object, Object, Boolean> {
|
||||
private static final String FRAGMENT_TAG = "import_settings_dialog";
|
||||
|
||||
private final DataImportActivity mActivity;
|
||||
private final String mPath;
|
||||
private final int mFlags;
|
||||
|
||||
ImportSettingsTask(final DataImportActivity activity, final String path, final int flags) {
|
||||
mActivity = activity;
|
||||
mPath = path;
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(final Object... params) {
|
||||
if (mPath == null) return false;
|
||||
final File file = new File(mPath);
|
||||
if (!file.isFile()) return false;
|
||||
try {
|
||||
DataImportExportUtils.importData(mActivity, file, mFlags);
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
final FragmentManager fm = mActivity.getSupportFragmentManager();
|
||||
final Fragment f = fm.findFragmentByTag(FRAGMENT_TAG);
|
||||
if (f instanceof DialogFragment) {
|
||||
((DialogFragment) f).dismiss();
|
||||
}
|
||||
if (result != null && result) {
|
||||
mActivity.setResult(RESULT_OK);
|
||||
} else {
|
||||
mActivity.setResult(RESULT_CANCELED);
|
||||
}
|
||||
mActivity.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
ProgressDialogFragment.show(mActivity, FRAGMENT_TAG).setCancelable(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OpenImportTypeTask extends AsyncTask<Object, Object, Integer> {
|
||||
|
||||
private static final String FRAGMENT_TAG = "read_settings_data_dialog";
|
||||
|
||||
private final DataImportActivity mActivity;
|
||||
private final String mPath;
|
||||
|
||||
OpenImportTypeTask(final DataImportActivity activity, final String path) {
|
||||
mActivity = activity;
|
||||
mPath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(final Object... params) {
|
||||
if (mPath == null) return 0;
|
||||
final File file = new File(mPath);
|
||||
if (!file.isFile()) return 0;
|
||||
try {
|
||||
return DataImportExportUtils.getImportedSettingsFlags(file);
|
||||
} catch (final IOException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Integer flags) {
|
||||
final FragmentManager fm = mActivity.getSupportFragmentManager();
|
||||
final Fragment f = fm.findFragmentByTag(FRAGMENT_TAG);
|
||||
if (f instanceof DialogFragment) {
|
||||
((DialogFragment) f).dismiss();
|
||||
}
|
||||
final DialogFragment df = new DataExportImportTypeSelectorDialogFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(EXTRA_PATH, mPath);
|
||||
args.putString(EXTRA_TITLE, mActivity.getString(R.string.import_settings_type_dialog_title));
|
||||
if (flags != null) {
|
||||
args.putInt(EXTRA_FLAGS, flags);
|
||||
} else {
|
||||
args.putInt(EXTRA_FLAGS, 0);
|
||||
}
|
||||
df.setArguments(args);
|
||||
df.show(mActivity.getSupportFragmentManager(), "select_import_type");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
ProgressDialogFragment.show(mActivity, FRAGMENT_TAG).setCancelable(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -68,12 +68,12 @@ public class KeyboardShortcutPreferenceCompatActivity extends BaseActivity imple
|
||||
switch (v.getId()) {
|
||||
case R.id.button_positive: {
|
||||
if (mKeySpec == null) return;
|
||||
mKeyboardShortcutsHandler.register(mKeySpec, getKeyAction());
|
||||
keyboardShortcutsHandler.register(mKeySpec, getKeyAction());
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
case R.id.button_neutral: {
|
||||
mKeyboardShortcutsHandler.unregister(getKeyAction());
|
||||
keyboardShortcutsHandler.unregister(getKeyAction());
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
@ -106,10 +106,10 @@ public class KeyboardShortcutPreferenceCompatActivity extends BaseActivity imple
|
||||
}
|
||||
mKeySpec = spec;
|
||||
mKeysLabel.setText(spec.toKeyString());
|
||||
final String oldAction = mKeyboardShortcutsHandler.findAction(spec);
|
||||
final String oldAction = keyboardShortcutsHandler.findAction(spec);
|
||||
final KeyboardShortcutSpec copyOfSpec = spec.copy();
|
||||
copyOfSpec.setContextTag(null);
|
||||
final String oldGeneralAction = mKeyboardShortcutsHandler.findAction(copyOfSpec);
|
||||
final String oldGeneralAction = keyboardShortcutsHandler.findAction(copyOfSpec);
|
||||
if (!TextUtils.isEmpty(oldAction) && !keyAction.equals(oldAction)) {
|
||||
// Conflicts with keys in same context tag
|
||||
mConflictLabel.setVisibility(View.VISIBLE);
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.util.StrictModeUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictModeUtils.detectAllVmPolicy();
|
||||
StrictModeUtils.detectAllThreadPolicy();
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
if (Utils.checkDeviceCompatible()) {
|
||||
final Intent intent = new Intent(this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
final Intent intent = new Intent(this, IncompatibleAlertActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
ThemeUtils.fixNightMode(getResources(), newConfig);
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
}
|
@ -171,13 +171,13 @@ public final class MediaViewerActivity extends BaseActivity implements IExtended
|
||||
CacheDownloadMediaViewerFragment f = (CacheDownloadMediaViewerFragment) object;
|
||||
final boolean running = f.getLoaderManager().hasRunningLoaders();
|
||||
final boolean downloaded = f.hasDownloadedData();
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !running && !downloaded);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.share, !running && downloaded);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.save, !running && downloaded);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.refresh, !running && !downloaded);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.share, !running && downloaded);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.save, !running && downloaded);
|
||||
} else {
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, false);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.share, true);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.save, false);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.refresh, false);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.share, true);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.save, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -169,14 +169,14 @@ public class QuickSearchBarActivity extends BaseActivity implements OnClickListe
|
||||
case SuggestionsAdapter.VIEW_TYPE_USER_SUGGESTION_ITEM: {
|
||||
IntentUtils.openUserProfile(this, getSelectedAccountKey(),
|
||||
UserKey.valueOf(item.extra_id), item.summary, null,
|
||||
mPreferences.getBoolean(KEY_NEW_DOCUMENT_API),
|
||||
preferences.getBoolean(KEY_NEW_DOCUMENT_API),
|
||||
Referral.DIRECT);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
case SuggestionsAdapter.VIEW_TYPE_USER_SCREEN_NAME: {
|
||||
IntentUtils.openUserProfile(this, getSelectedAccountKey(), null, item.title, null,
|
||||
mPreferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.DIRECT);
|
||||
preferences.getBoolean(KEY_NEW_DOCUMENT_API), Referral.DIRECT);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
@ -346,8 +346,8 @@ public class QuickSearchBarActivity extends BaseActivity implements OnClickListe
|
||||
super(activity, null, 0);
|
||||
mRemovedPositions = new SortableIntList();
|
||||
mActivity = activity;
|
||||
mMediaLoader = activity.mMediaLoader;
|
||||
mUserColorNameManager = activity.mUserColorNameManager;
|
||||
mMediaLoader = activity.mediaLoader;
|
||||
mUserColorNameManager = activity.userColorNameManager;
|
||||
mInflater = LayoutInflater.from(activity);
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ public class RequestPermissionsActivity extends BaseActivity implements OnClickL
|
||||
public void onClick(final View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.accept: {
|
||||
mPermissionsManager.accept(mCallingPackage, mPermissions);
|
||||
permissionsManager.accept(mCallingPackage, mPermissions);
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
break;
|
||||
@ -91,7 +91,7 @@ public class RequestPermissionsActivity extends BaseActivity implements OnClickL
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (mPermissionsManager.isDenied(caller)) {
|
||||
if (permissionsManager.isDenied(caller)) {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
return;
|
||||
|
@ -1,696 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.afollestad.appthemeengine.Config;
|
||||
import com.afollestad.appthemeengine.util.ATEUtil;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.annotation.CustomTabType;
|
||||
import org.mariotaku.twidere.fragment.BaseDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.BasePreferenceFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseSupportFragment;
|
||||
import org.mariotaku.twidere.fragment.DirectMessagesFragment;
|
||||
import org.mariotaku.twidere.fragment.HomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.InteractionsTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.MessagesEntriesFragment;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
||||
import org.mariotaku.twidere.model.SupportTabSpec;
|
||||
import org.mariotaku.twidere.preference.WizardPageHeaderPreference;
|
||||
import org.mariotaku.twidere.preference.WizardPageNavPreference;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.CustomTabUtils;
|
||||
import org.mariotaku.twidere.util.InternalParseUtils;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereMathUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.LinePageIndicator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsWizardActivity extends BaseActivity {
|
||||
|
||||
public static final String WIZARD_PREFERENCE_KEY_NEXT_PAGE = "next_page";
|
||||
public static final String WIZARD_PREFERENCE_KEY_USE_DEFAULTS = "use_defaults";
|
||||
public static final String WIZARD_PREFERENCE_KEY_EDIT_CUSTOM_TABS = "edit_custom_tabs";
|
||||
public static final String WIZARD_PREFERENCE_KEY_IMPORT_SETTINGS = "import_settings";
|
||||
|
||||
private static final int REQUEST_IMPORT_SETTINGS = 201;
|
||||
|
||||
private ViewPager mViewPager;
|
||||
|
||||
private LinePageIndicator mIndicator;
|
||||
private SupportTabsAdapter mAdapter;
|
||||
|
||||
private AbsInitialSettingsTask mTask;
|
||||
|
||||
public void applyInitialSettings() {
|
||||
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return;
|
||||
mTask = new InitialSettingsTask(this);
|
||||
AsyncTaskUtils.executeTask(mTask);
|
||||
}
|
||||
|
||||
public void applyInitialTabSettings() {
|
||||
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) return;
|
||||
mTask = new InitialTabSettingsTask(this);
|
||||
AsyncTaskUtils.executeTask(mTask);
|
||||
}
|
||||
|
||||
public void exitWizard() {
|
||||
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||
prefs.edit().putBoolean(KEY_SETTINGS_WIZARD_COMPLETED, true).apply();
|
||||
final Intent intent = new Intent(this, HomeActivity.class);
|
||||
intent.putExtra(EXTRA_OPEN_ACCOUNTS_DRAWER, true);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
public void gotoFinishPage() {
|
||||
if (mViewPager == null || mAdapter == null) return;
|
||||
final int last = mAdapter.getCount() - 1;
|
||||
mViewPager.setCurrentItem(Math.max(last, 0));
|
||||
}
|
||||
|
||||
public void gotoLastPage() {
|
||||
if (mViewPager == null || mAdapter == null) return;
|
||||
gotoPage(getPageCount() - 2);
|
||||
}
|
||||
|
||||
public void gotoNextPage() {
|
||||
if (mViewPager == null || mAdapter == null) return;
|
||||
final int current = mViewPager.getCurrentItem();
|
||||
mViewPager.setCurrentItem(TwidereMathUtils.clamp(current + 1, mAdapter.getCount() - 1, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentChanged() {
|
||||
super.onContentChanged();
|
||||
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||
mIndicator = (LinePageIndicator) findViewById(R.id.indicator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusBarColor() {
|
||||
if (VALUE_THEME_NAME_DARK.equals(getATEKey())) return Color.BLACK;
|
||||
return ATEUtil.darkenColor(ThemeUtils.getColorBackground(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_IMPORT_SETTINGS: {
|
||||
if (resultCode == RESULT_OK) {
|
||||
gotoLastPage();
|
||||
} else {
|
||||
gotoNextPage();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThemeBackgroundOption() {
|
||||
return ThemeUtils.getThemeBackgroundOption(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings_wizard);
|
||||
mAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), null);
|
||||
mViewPager.setAdapter(mAdapter);
|
||||
mViewPager.setEnabled(false);
|
||||
mIndicator.setViewPager(mViewPager);
|
||||
mIndicator.setSelectedColor(Config.accentColor(this, getATEKey()));
|
||||
initPages();
|
||||
final int initialPage = getIntent().getIntExtra(EXTRA_PAGE, -1);
|
||||
if (initialPage != -1) {
|
||||
mViewPager.setCurrentItem(initialPage, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void initPages() {
|
||||
mAdapter.addTab(WizardPageWelcomeFragment.class, null, getString(R.string.wizard_page_welcome_title), null, 0, null);
|
||||
mAdapter.addTab(WizardPageThemeFragment.class, null, getString(R.string.theme), null, 0, null);
|
||||
mAdapter.addTab(WizardPageTabsFragment.class, null, getString(R.string.tabs), null, 0, null);
|
||||
mAdapter.addTab(WizardPageCardsFragment.class, null, getString(R.string.cards), null, 0, null);
|
||||
mAdapter.addTab(WizardPageUsageStatisticsFragment.class, null, getString(R.string.usage_statistics), null, 0, null);
|
||||
mAdapter.addTab(WizardPageHintsFragment.class, null, getString(R.string.hints), null, 0, null);
|
||||
mAdapter.addTab(WizardPageFinishedFragment.class, null, getString(R.string.wizard_page_finished_title), null, 0, null);
|
||||
}
|
||||
|
||||
private void openImportSettingsDialog() {
|
||||
final Intent intent = new Intent(this, DataImportActivity.class);
|
||||
startActivityForResult(intent, REQUEST_IMPORT_SETTINGS);
|
||||
}
|
||||
|
||||
public static abstract class BaseWizardPageFragment extends BasePreferenceFragment implements
|
||||
Preference.OnPreferenceClickListener {
|
||||
|
||||
public void gotoFinishPage() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).gotoFinishPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void gotoLastPage() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).gotoLastPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void gotoNextPage() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).gotoNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
final PreferenceManager preferenceManager = getPreferenceManager();
|
||||
preferenceManager.setSharedPreferencesName(SHARED_PREFERENCES_NAME);
|
||||
addPreferencesFromResource(getPreferenceResource());
|
||||
|
||||
final Context context = getActivity();
|
||||
final Preference wizardHeader = new WizardPageHeaderPreference(context);
|
||||
wizardHeader.setTitle(getHeaderTitle());
|
||||
wizardHeader.setSummary(getHeaderSummary());
|
||||
wizardHeader.setOrder(0);
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
screen.addPreference(wizardHeader);
|
||||
final int nextPageTitle = getNextPageTitle();
|
||||
if (nextPageTitle != 0) {
|
||||
final Preference nextPage = new WizardPageNavPreference(context);
|
||||
nextPage.setOrder(999);
|
||||
nextPage.setKey(WIZARD_PREFERENCE_KEY_NEXT_PAGE);
|
||||
nextPage.setTitle(nextPageTitle);
|
||||
nextPage.setOnPreferenceClickListener(this);
|
||||
screen.addPreference(nextPage);
|
||||
}
|
||||
|
||||
|
||||
final Preference.OnPreferenceChangeListener listener = new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final Bundle extras = preference.getExtras();
|
||||
if (extras != null && extras.getBoolean(EXTRA_RESTART_ACTIVITY)) {
|
||||
((SettingsWizardActivity) getActivity()).restartWithCurrentPage();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0, j = screen.getPreferenceCount(); i < j; i++) {
|
||||
screen.getPreference(i).setOnPreferenceChangeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(final Preference preference) {
|
||||
if (WIZARD_PREFERENCE_KEY_NEXT_PAGE.equals(preference.getKey())) {
|
||||
gotoNextPage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract int getHeaderSummary();
|
||||
|
||||
protected abstract int getHeaderTitle();
|
||||
|
||||
protected int getNextPageTitle() {
|
||||
return R.string.next_step;
|
||||
}
|
||||
|
||||
protected abstract int getPreferenceResource();
|
||||
|
||||
}
|
||||
|
||||
private void restartWithCurrentPage() {
|
||||
final Intent intent = getIntent();
|
||||
intent.putExtra(EXTRA_PAGE, mViewPager.getCurrentItem());
|
||||
setIntent(intent);
|
||||
recreate();
|
||||
}
|
||||
|
||||
public static class WizardPageCardsFragment extends BaseWizardPageFragment {
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_cards_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.cards;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.preferences_cards;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WizardPageFinishedFragment extends BaseSupportFragment implements OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).exitWizard();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final View view = inflater.inflate(R.layout.fragment_wizard_page_finished, container, false);
|
||||
view.findViewById(R.id.exit_wizard).setOnClickListener(this);
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WizardPageUsageStatisticsFragment extends BaseWizardPageFragment {
|
||||
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_usage_statistics_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.usage_statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNextPageTitle() {
|
||||
return R.string.next_step;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.settings_wizard_page_usage_statistics;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WizardPageHintsFragment extends BaseWizardPageFragment {
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_hints_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.hints;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNextPageTitle() {
|
||||
return R.string.finish;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.settings_wizard_page_hints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
super.gotoNextPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gotoNextPage() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
final String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||
requestPermissions(permissions, REQUEST_REQUEST_PERMISSIONS);
|
||||
} else {
|
||||
// Try getting location, some custom rom will popup requirement dialog
|
||||
Utils.getCachedLocation(getActivity());
|
||||
super.gotoNextPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class WizardPageTabsFragment extends BaseWizardPageFragment {
|
||||
|
||||
private static final int REQUEST_CUSTOM_TABS = 1;
|
||||
|
||||
public void applyInitialTabSettings() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).applyInitialTabSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
findPreference(WIZARD_PREFERENCE_KEY_EDIT_CUSTOM_TABS).setOnPreferenceClickListener(this);
|
||||
findPreference(WIZARD_PREFERENCE_KEY_USE_DEFAULTS).setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_CUSTOM_TABS:
|
||||
if (resultCode != RESULT_OK) {
|
||||
new TabsUnchangedDialogFragment().show(getFragmentManager(), "tabs_unchanged");
|
||||
} else {
|
||||
gotoNextPage();
|
||||
}
|
||||
break;
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(final Preference preference) {
|
||||
final String key = preference.getKey();
|
||||
if (WIZARD_PREFERENCE_KEY_EDIT_CUSTOM_TABS.equals(key)) {
|
||||
final Intent intent = new Intent(getActivity(), SettingsActivity.class);
|
||||
intent.putExtra(SettingsActivity.EXTRA_INITIAL_TAG, "tabs");
|
||||
startActivityForResult(intent, REQUEST_CUSTOM_TABS);
|
||||
} else if (WIZARD_PREFERENCE_KEY_USE_DEFAULTS.equals(key)) {
|
||||
applyInitialTabSettings();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_tabs_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.tabs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNextPageTitle() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.settings_wizard_page_tab;
|
||||
}
|
||||
|
||||
public static class TabsUnchangedDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onCancel(final DialogInterface dialog) {
|
||||
gotoNextPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
gotoNextPage();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(R.string.wizard_page_tabs_unchanged_message);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private void gotoNextPage() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).gotoNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class WizardPageThemeFragment extends BaseWizardPageFragment implements Preference.OnPreferenceClickListener {
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_theme_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.preferences_theme;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WizardPageWelcomeFragment extends BaseWizardPageFragment implements Preference.OnPreferenceClickListener {
|
||||
|
||||
public void applyInitialSettings() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).applyInitialSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
findPreference(WIZARD_PREFERENCE_KEY_NEXT_PAGE).setOnPreferenceClickListener(this);
|
||||
findPreference(WIZARD_PREFERENCE_KEY_USE_DEFAULTS).setOnPreferenceClickListener(this);
|
||||
findPreference(WIZARD_PREFERENCE_KEY_IMPORT_SETTINGS).setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(final Preference preference) {
|
||||
final String key = preference.getKey();
|
||||
if (WIZARD_PREFERENCE_KEY_NEXT_PAGE.equals(key)) {
|
||||
gotoNextPage();
|
||||
} else if (WIZARD_PREFERENCE_KEY_USE_DEFAULTS.equals(key)) {
|
||||
applyInitialSettings();
|
||||
} else if (WIZARD_PREFERENCE_KEY_IMPORT_SETTINGS.equals(key)) {
|
||||
openImportSettingsDialog();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderSummary() {
|
||||
return R.string.wizard_page_welcome_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTitle() {
|
||||
return R.string.wizard_page_welcome_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNextPageTitle() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceResource() {
|
||||
return R.xml.settings_wizard_page_welcome;
|
||||
}
|
||||
|
||||
private void openImportSettingsDialog() {
|
||||
final Activity a = getActivity();
|
||||
if (a instanceof SettingsWizardActivity) {
|
||||
((SettingsWizardActivity) a).openImportSettingsDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static abstract class AbsInitialSettingsTask extends AsyncTask<Object, Object, Boolean> {
|
||||
|
||||
private static final String FRAGMENT_TAG = "initial_settings_dialog";
|
||||
|
||||
private static final String[] DEFAULT_TAB_TYPES = {CustomTabType.HOME_TIMELINE,
|
||||
CustomTabType.NOTIFICATIONS_TIMELINE, CustomTabType.TRENDS_SUGGESTIONS,
|
||||
CustomTabType.DIRECT_MESSAGES};
|
||||
|
||||
private final SettingsWizardActivity mActivity;
|
||||
|
||||
AbsInitialSettingsTask(final SettingsWizardActivity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(final Object... params) {
|
||||
final ContentResolver resolver = mActivity.getContentResolver();
|
||||
final List<SupportTabSpec> tabs = CustomTabUtils.getHomeTabs(mActivity);
|
||||
if (wasConfigured(tabs)) return true;
|
||||
Collections.sort(tabs);
|
||||
int i = 0;
|
||||
final List<ContentValues> values_list = new ArrayList<>();
|
||||
for (final String type : DEFAULT_TAB_TYPES) {
|
||||
final ContentValues values = new ContentValues();
|
||||
final CustomTabConfiguration conf = CustomTabUtils.getTabConfiguration(type);
|
||||
values.put(Tabs.TYPE, type);
|
||||
values.put(Tabs.ICON, CustomTabUtils.findTabIconKey(conf.getDefaultIcon()));
|
||||
values.put(Tabs.POSITION, i++);
|
||||
values_list.add(values);
|
||||
}
|
||||
for (final SupportTabSpec spec : tabs) {
|
||||
final String type = CustomTabUtils.findTabType(spec.cls);
|
||||
if (type != null) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(Tabs.TYPE, type);
|
||||
values.put(Tabs.ARGUMENTS, InternalParseUtils.bundleToJSON(spec.args));
|
||||
values.put(Tabs.NAME, ParseUtils.parseString(spec.name));
|
||||
if (spec.icon instanceof Integer) {
|
||||
values.put(Tabs.ICON, CustomTabUtils.findTabIconKey((Integer) spec.icon));
|
||||
} else if (spec.icon instanceof File) {
|
||||
values.put(Tabs.ICON, ((File) spec.icon).getPath());
|
||||
}
|
||||
values.put(Tabs.POSITION, i++);
|
||||
}
|
||||
}
|
||||
resolver.delete(Tabs.CONTENT_URI, null, null);
|
||||
resolver.bulkInsert(Tabs.CONTENT_URI, values_list.toArray(new ContentValues[values_list.size()]));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected SettingsWizardActivity getActivity() {
|
||||
return mActivity;
|
||||
}
|
||||
|
||||
protected abstract void nextStep();
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
final FragmentManager fm = mActivity.getSupportFragmentManager();
|
||||
final DialogFragment f = (DialogFragment) fm.findFragmentByTag(FRAGMENT_TAG);
|
||||
if (f != null) {
|
||||
f.dismiss();
|
||||
}
|
||||
nextStep();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
ProgressDialogFragment.show(mActivity, FRAGMENT_TAG).setCancelable(false);
|
||||
}
|
||||
|
||||
private boolean wasConfigured(final List<SupportTabSpec> tabs) {
|
||||
for (final SupportTabSpec spec : tabs) {
|
||||
if (spec.cls == HomeTimelineFragment.class
|
||||
|| spec.cls == InteractionsTimelineFragment.class
|
||||
|| spec.cls == DirectMessagesFragment.class
|
||||
|| spec.cls == MessagesEntriesFragment.class) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class InitialSettingsTask extends AbsInitialSettingsTask {
|
||||
|
||||
InitialSettingsTask(final SettingsWizardActivity activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void nextStep() {
|
||||
final SettingsWizardActivity activity = getActivity();
|
||||
activity.gotoPage(activity.getPageCount() - 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void gotoPage(int page) {
|
||||
mViewPager.setCurrentItem(TwidereMathUtils.clamp(page, 0, getPageCount() - 1));
|
||||
}
|
||||
|
||||
private int getPageCount() {
|
||||
return mAdapter.getCount();
|
||||
}
|
||||
|
||||
static class InitialTabSettingsTask extends AbsInitialSettingsTask {
|
||||
|
||||
InitialTabSettingsTask(final SettingsWizardActivity activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void nextStep() {
|
||||
getActivity().gotoNextPage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -346,10 +346,10 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
|
||||
ViewCompat.setBackgroundTintList(mSignInButton, color);
|
||||
|
||||
|
||||
final String consumerKey = mPreferences.getString(KEY_CONSUMER_KEY, null);
|
||||
final String consumerSecret = mPreferences.getString(KEY_CONSUMER_SECRET, null);
|
||||
final String consumerKey = preferences.getString(KEY_CONSUMER_KEY, null);
|
||||
final String consumerSecret = preferences.getString(KEY_CONSUMER_SECRET, null);
|
||||
if (BuildConfig.SHOW_CUSTOM_TOKEN_DIALOG && savedInstanceState == null &&
|
||||
!mPreferences.getBoolean(KEY_CONSUMER_KEY_SECRET_SET, false) &&
|
||||
!preferences.getBoolean(KEY_CONSUMER_KEY_SECRET_SET, false) &&
|
||||
!Utils.isCustomConsumerKeySecret(consumerKey, consumerSecret)) {
|
||||
final SetConsumerKeySecretDialogFragment df = new SetConsumerKeySecretDialogFragment();
|
||||
df.setCancelable(false);
|
||||
@ -396,14 +396,14 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
|
||||
|
||||
|
||||
private void setDefaultAPI() {
|
||||
final long apiLastChange = mPreferences.getLong(KEY_API_LAST_CHANGE, mAPIChangeTimestamp);
|
||||
final long apiLastChange = preferences.getLong(KEY_API_LAST_CHANGE, mAPIChangeTimestamp);
|
||||
final boolean defaultApiChanged = apiLastChange != mAPIChangeTimestamp;
|
||||
final String apiUrlFormat = Utils.getNonEmptyString(mPreferences, KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT);
|
||||
final int authType = mPreferences.getInt(KEY_AUTH_TYPE, AuthType.OAUTH);
|
||||
final boolean sameOAuthSigningUrl = mPreferences.getBoolean(KEY_SAME_OAUTH_SIGNING_URL, false);
|
||||
final boolean noVersionSuffix = mPreferences.getBoolean(KEY_NO_VERSION_SUFFIX, false);
|
||||
final String consumerKey = Utils.getNonEmptyString(mPreferences, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY);
|
||||
final String consumerSecret = Utils.getNonEmptyString(mPreferences, KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET);
|
||||
final String apiUrlFormat = Utils.getNonEmptyString(preferences, KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT);
|
||||
final int authType = preferences.getInt(KEY_AUTH_TYPE, AuthType.OAUTH);
|
||||
final boolean sameOAuthSigningUrl = preferences.getBoolean(KEY_SAME_OAUTH_SIGNING_URL, false);
|
||||
final boolean noVersionSuffix = preferences.getBoolean(KEY_NO_VERSION_SUFFIX, false);
|
||||
final String consumerKey = Utils.getNonEmptyString(preferences, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY);
|
||||
final String consumerSecret = Utils.getNonEmptyString(preferences, KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET);
|
||||
if (TextUtils.isEmpty(mAPIUrlFormat) || defaultApiChanged) {
|
||||
mAPIUrlFormat = apiUrlFormat;
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.SettingsDetailsFragment;
|
||||
|
||||
public class UsageStatisticsActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (!mPreferences.contains(KEY_USAGE_STATISTICS)) {
|
||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||
editor.putBoolean(KEY_USAGE_STATISTICS, mPreferences.getBoolean(KEY_USAGE_STATISTICS));
|
||||
editor.apply();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final Bundle fragmentArgs = new Bundle();
|
||||
fragmentArgs.putInt(EXTRA_RESID, R.xml.preferences_usage_statistics);
|
||||
final FragmentManager fm = getSupportFragmentManager();
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
ft.replace(android.R.id.content, Fragment.instantiate(this,
|
||||
SettingsDetailsFragment.class.getName(), fragmentArgs));
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
}
|
@ -196,12 +196,12 @@ public class UserListSelectorActivity extends BaseActivity implements OnClickLis
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mBus.register(this);
|
||||
bus.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
mBus.unregister(this);
|
||||
bus.unregister(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
|
@ -17,16 +17,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity.iface;
|
||||
package org.mariotaku.twidere.activity.iface
|
||||
|
||||
public interface IThemedActivity {
|
||||
interface IThemedActivity {
|
||||
|
||||
int getCurrentThemeBackgroundAlpha();
|
||||
val currentThemeBackgroundAlpha: Int
|
||||
|
||||
String getCurrentThemeBackgroundOption();
|
||||
val currentThemeBackgroundOption: String
|
||||
|
||||
int getThemeBackgroundAlpha();
|
||||
val themeBackgroundAlpha: Int
|
||||
|
||||
String getThemeBackgroundOption();
|
||||
val themeBackgroundOption: String
|
||||
|
||||
}
|
@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
|
||||
@ -67,7 +68,7 @@ public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements Constants, I
|
||||
super(context, layoutRes, collection);
|
||||
//noinspection unchecked
|
||||
GeneralComponentHelper.build(context).inject((BaseArrayAdapter<Object>) this);
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
final TwidereApplication app = TwidereApplication.Companion.getInstance(context);
|
||||
mLinkify = new TwidereLinkify(new OnLinkClickHandler(context, mMultiSelectManager, mPreferences));
|
||||
mNicknamePrefs = context.getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mColorPrefs = context.getSharedPreferences(USER_COLOR_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
@ -75,6 +76,7 @@ public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements Constants, I
|
||||
mColorPrefs.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MediaLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
@ -128,7 +130,7 @@ public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements Constants, I
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLinkHighlightOption(final String option) {
|
||||
public final void setLinkHighlightOption(@NonNull final String option) {
|
||||
final int optionInt = Utils.getLinkHighlightingStyleInt(option);
|
||||
mLinkify.setHighlightOption(optionInt);
|
||||
if (optionInt == mLinkHighlightOption) return;
|
||||
|
@ -42,8 +42,8 @@ public class SourceAutoCompleteAdapter extends SimpleCursorAdapter {
|
||||
|
||||
public SourceAutoCompleteAdapter(final Context context) {
|
||||
super(context, android.R.layout.simple_list_item_1, null, FROM, TO, 0);
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mDatabase = app.getSQLiteDatabase();
|
||||
final TwidereApplication app = TwidereApplication.Companion.getInstance(context);
|
||||
mDatabase = app.getSqLiteDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,421 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.app;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.multidex.MultiDex;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
import android.support.v7.widget.ActionBarContextView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.appthemeengine.ATE;
|
||||
import com.afollestad.appthemeengine.Config;
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
import com.rengwuxian.materialedittext.MaterialEditText;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.AssistLauncherActivity;
|
||||
import org.mariotaku.twidere.activity.MainActivity;
|
||||
import org.mariotaku.twidere.activity.MainHondaJOJOActivity;
|
||||
import org.mariotaku.twidere.service.RefreshService;
|
||||
import org.mariotaku.twidere.util.BugReporter;
|
||||
import org.mariotaku.twidere.util.DebugModeUtils;
|
||||
import org.mariotaku.twidere.util.ExternalThemeManager;
|
||||
import org.mariotaku.twidere.util.HttpClientFactory;
|
||||
import org.mariotaku.twidere.util.StrictModeUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereBugReporter;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper;
|
||||
import org.mariotaku.twidere.util.dagger.DependencyHolder;
|
||||
import org.mariotaku.twidere.util.net.TwidereDns;
|
||||
import org.mariotaku.twidere.util.theme.ActionBarContextViewViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.FloatingActionButtonViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.FontFamilyTagProcessor;
|
||||
import org.mariotaku.twidere.util.theme.IconActionButtonTagProcessor;
|
||||
import org.mariotaku.twidere.util.theme.ImageViewViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.MaterialEditTextViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.OptimalLinkColorTagProcessor;
|
||||
import org.mariotaku.twidere.util.theme.ProfileImageViewViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.ProgressWheelViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.SwipeRefreshLayoutViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.TabPagerIndicatorViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.TextViewViewProcessor;
|
||||
import org.mariotaku.twidere.util.theme.TimelineContentTextViewViewProcessor;
|
||||
import org.mariotaku.twidere.view.ProfileImageView;
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator;
|
||||
import org.mariotaku.twidere.view.ThemedMultiValueSwitch;
|
||||
import org.mariotaku.twidere.view.TimelineContentTextView;
|
||||
|
||||
public class TwidereApplication extends Application implements Constants,
|
||||
OnSharedPreferenceChangeListener {
|
||||
|
||||
private static final String KEY_UCD_DATA_PROFILING = "ucd_data_profiling";
|
||||
private static final String KEY_SPICE_DATA_PROFILING = "spice_data_profiling";
|
||||
private static final String KEY_KEYBOARD_SHORTCUT_INITIALIZED = "keyboard_shortcut_initialized";
|
||||
private static TwidereApplication sInstance;
|
||||
|
||||
private Handler mHandler;
|
||||
private SharedPreferences mPreferences;
|
||||
private SQLiteOpenHelper mSQLiteOpenHelper;
|
||||
private SQLiteDatabase mDatabase;
|
||||
|
||||
private ProfileImageViewViewProcessor mProfileImageViewViewProcessor;
|
||||
private FontFamilyTagProcessor mFontFamilyTagProcessor;
|
||||
|
||||
@NonNull
|
||||
public static TwidereApplication getInstance(@NonNull final Context context) {
|
||||
return (TwidereApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context base) {
|
||||
super.attachBaseContext(base);
|
||||
MultiDex.install(this);
|
||||
}
|
||||
|
||||
public Handler getHandler() {
|
||||
return mHandler;
|
||||
}
|
||||
|
||||
public void initKeyboardShortcuts() {
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
if (!preferences.getBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, false)) {
|
||||
// getApplicationModule().getKeyboardShortcutsHandler().reset();
|
||||
preferences.edit().putBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, true).apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SQLiteDatabase getSQLiteDatabase() {
|
||||
if (mDatabase != null) return mDatabase;
|
||||
StrictModeUtils.checkDiskIO();
|
||||
return mDatabase = getSQLiteOpenHelper().getWritableDatabase();
|
||||
}
|
||||
|
||||
public SQLiteOpenHelper getSQLiteOpenHelper() {
|
||||
if (mSQLiteOpenHelper != null) return mSQLiteOpenHelper;
|
||||
return mSQLiteOpenHelper = new TwidereSQLiteOpenHelper(this, DATABASES_NAME, DATABASES_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
sInstance = this;
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictModeUtils.detectAllVmPolicy();
|
||||
}
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
resetTheme(preferences);
|
||||
super.onCreate();
|
||||
|
||||
mProfileImageViewViewProcessor = new ProfileImageViewViewProcessor();
|
||||
mFontFamilyTagProcessor = new FontFamilyTagProcessor();
|
||||
|
||||
ATE.registerViewProcessor(TabPagerIndicator.class, new TabPagerIndicatorViewProcessor());
|
||||
ATE.registerViewProcessor(FloatingActionButton.class, new FloatingActionButtonViewProcessor());
|
||||
ATE.registerViewProcessor(ActionBarContextView.class, new ActionBarContextViewViewProcessor());
|
||||
ATE.registerViewProcessor(SwipeRefreshLayout.class, new SwipeRefreshLayoutViewProcessor());
|
||||
ATE.registerViewProcessor(TimelineContentTextView.class, new TimelineContentTextViewViewProcessor());
|
||||
ATE.registerViewProcessor(TextView.class, new TextViewViewProcessor());
|
||||
ATE.registerViewProcessor(ImageView.class, new ImageViewViewProcessor());
|
||||
ATE.registerViewProcessor(MaterialEditText.class, new MaterialEditTextViewProcessor());
|
||||
ATE.registerViewProcessor(ProgressWheel.class, new ProgressWheelViewProcessor());
|
||||
ATE.registerViewProcessor(ProfileImageView.class, mProfileImageViewViewProcessor);
|
||||
ATE.registerTagProcessor(OptimalLinkColorTagProcessor.TAG, new OptimalLinkColorTagProcessor());
|
||||
ATE.registerTagProcessor(FontFamilyTagProcessor.TAG, mFontFamilyTagProcessor);
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR,
|
||||
new IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR));
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_ACTIVATED,
|
||||
new IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_ACTIVATED));
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_DISABLED,
|
||||
new IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_DISABLED));
|
||||
ATE.registerTagProcessor(ThemedMultiValueSwitch.PREFIX_TINT, new ThemedMultiValueSwitch.TintTagProcessor());
|
||||
|
||||
|
||||
mProfileImageViewViewProcessor.setStyle(Utils.getProfileImageStyle(preferences));
|
||||
mFontFamilyTagProcessor.setFontFamily(ThemeUtils.getThemeFontFamily(preferences));
|
||||
|
||||
final int themeColor = preferences.getInt(KEY_THEME_COLOR, ContextCompat.getColor(this,
|
||||
R.color.branding_color));
|
||||
if (!ATE.config(this, VALUE_THEME_NAME_LIGHT).isConfigured()) {
|
||||
//noinspection WrongConstant
|
||||
ATE.config(this, VALUE_THEME_NAME_LIGHT)
|
||||
.primaryColor(themeColor)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK))
|
||||
.coloredActionBar(true)
|
||||
.coloredStatusBar(true)
|
||||
.commit();
|
||||
}
|
||||
if (!ATE.config(this, VALUE_THEME_NAME_DARK).isConfigured()) {
|
||||
ATE.config(this, VALUE_THEME_NAME_DARK)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE))
|
||||
.coloredActionBar(false)
|
||||
.coloredStatusBar(true)
|
||||
.statusBarColor(Color.BLACK)
|
||||
.commit();
|
||||
}
|
||||
if (!ATE.config(this, null).isConfigured()) {
|
||||
ATE.config(this, null)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE))
|
||||
.coloredActionBar(false)
|
||||
.coloredStatusBar(false)
|
||||
.commit();
|
||||
}
|
||||
initializeAsyncTask();
|
||||
initDebugMode();
|
||||
initBugReport();
|
||||
mHandler = new Handler();
|
||||
|
||||
final PackageManager pm = getPackageManager();
|
||||
final ComponentName main = new ComponentName(this, MainActivity.class);
|
||||
final ComponentName main2 = new ComponentName(this, MainHondaJOJOActivity.class);
|
||||
final boolean mainDisabled = pm.getComponentEnabledSetting(main) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
|
||||
final boolean main2Disabled = pm.getComponentEnabledSetting(main2) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
|
||||
final boolean noEntry = mainDisabled && main2Disabled;
|
||||
if (noEntry) {
|
||||
pm.setComponentEnabledSetting(main, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
} else if (!mainDisabled) {
|
||||
pm.setComponentEnabledSetting(main2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
if (!Utils.isComposeNowSupported(this)) {
|
||||
final ComponentName assist = new ComponentName(this, AssistLauncherActivity.class);
|
||||
pm.setComponentEnabledSetting(assist, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
migrateUsageStatisticsPreferences();
|
||||
Utils.startRefreshServiceIfNeeded(this);
|
||||
|
||||
DependencyHolder holder = DependencyHolder.get(this);
|
||||
registerActivityLifecycleCallbacks(holder.getActivityTracker());
|
||||
|
||||
final IntentFilter packageFilter = new IntentFilter();
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
|
||||
registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
|
||||
final String[] packages = getPackageManager().getPackagesForUid(uid);
|
||||
DependencyHolder holder = DependencyHolder.get(context);
|
||||
final ExternalThemeManager manager = holder.getExternalThemeManager();
|
||||
if (ArrayUtils.contains(packages, manager.getEmojiPackageName())) {
|
||||
manager.reloadEmojiPreferences();
|
||||
}
|
||||
}
|
||||
}, packageFilter);
|
||||
}
|
||||
|
||||
private void initDebugMode() {
|
||||
DebugModeUtils.initForApplication(this);
|
||||
}
|
||||
|
||||
private void initBugReport() {
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
if (!preferences.getBoolean(KEY_BUG_REPORTS, BuildConfig.DEBUG)) return;
|
||||
BugReporter.setImplementation(new TwidereBugReporter());
|
||||
BugReporter.init(this);
|
||||
}
|
||||
|
||||
private void migrateUsageStatisticsPreferences() {
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
final boolean hasUsageStatistics = preferences.contains(KEY_USAGE_STATISTICS);
|
||||
if (hasUsageStatistics) return;
|
||||
if (preferences.contains(KEY_UCD_DATA_PROFILING) || preferences.contains(KEY_SPICE_DATA_PROFILING)) {
|
||||
final boolean prevUsageEnabled = preferences.getBoolean(KEY_UCD_DATA_PROFILING, false)
|
||||
|| preferences.getBoolean(KEY_SPICE_DATA_PROFILING, false);
|
||||
final Editor editor = preferences.edit();
|
||||
editor.putBoolean(KEY_USAGE_STATISTICS, prevUsageEnabled);
|
||||
editor.remove(KEY_UCD_DATA_PROFILING);
|
||||
editor.remove(KEY_SPICE_DATA_PROFILING);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
private SharedPreferences getSharedPreferences() {
|
||||
if (mPreferences != null) return mPreferences;
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||
return mPreferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrimMemory(int level) {
|
||||
super.onTrimMemory(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
final DependencyHolder holder = DependencyHolder.get(this);
|
||||
super.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
switch (key) {
|
||||
case KEY_REFRESH_INTERVAL: {
|
||||
stopService(new Intent(this, RefreshService.class));
|
||||
Utils.startRefreshServiceIfNeeded(this);
|
||||
break;
|
||||
}
|
||||
case KEY_ENABLE_PROXY:
|
||||
case KEY_PROXY_HOST:
|
||||
case KEY_PROXY_PORT:
|
||||
case KEY_PROXY_TYPE:
|
||||
case KEY_PROXY_USERNAME:
|
||||
case KEY_PROXY_PASSWORD:
|
||||
case KEY_CONNECTION_TIMEOUT:
|
||||
case KEY_RETRY_ON_NETWORK_ISSUE: {
|
||||
HttpClientFactory.reloadConnectivitySettings(this);
|
||||
break;
|
||||
}
|
||||
case KEY_DNS_SERVER:
|
||||
case KEY_TCP_DNS_QUERY:
|
||||
case KEY_BUILTIN_DNS_RESOLVER: {
|
||||
reloadDnsSettings();
|
||||
break;
|
||||
}
|
||||
case KEY_CONSUMER_KEY:
|
||||
case KEY_CONSUMER_SECRET:
|
||||
case KEY_API_URL_FORMAT:
|
||||
case KEY_AUTH_TYPE:
|
||||
case KEY_SAME_OAUTH_SIGNING_URL:
|
||||
case KEY_THUMBOR_ENABLED:
|
||||
case KEY_THUMBOR_ADDRESS:
|
||||
case KEY_THUMBOR_SECURITY_KEY: {
|
||||
final Editor editor = preferences.edit();
|
||||
editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis());
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
case KEY_EMOJI_SUPPORT: {
|
||||
DependencyHolder.get(this).getExternalThemeManager().reloadEmojiPreferences();
|
||||
break;
|
||||
}
|
||||
case KEY_THEME: {
|
||||
resetTheme(preferences);
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK);
|
||||
break;
|
||||
}
|
||||
case KEY_THEME_BACKGROUND: {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK);
|
||||
break;
|
||||
}
|
||||
case KEY_PROFILE_IMAGE_STYLE: {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK);
|
||||
mProfileImageViewViewProcessor.setStyle(Utils.getProfileImageStyle(preferences.getString(key, null)));
|
||||
break;
|
||||
}
|
||||
case KEY_THEME_FONT_FAMILY: {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK);
|
||||
mFontFamilyTagProcessor.setFontFamily(ThemeUtils.getThemeFontFamily(preferences));
|
||||
break;
|
||||
}
|
||||
case KEY_THEME_COLOR: {
|
||||
final int themeColor = preferences.getInt(key, ContextCompat.getColor(this,
|
||||
R.color.branding_color));
|
||||
//noinspection WrongConstant
|
||||
ATE.config(this, VALUE_THEME_NAME_LIGHT)
|
||||
.primaryColor(themeColor)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK))
|
||||
.coloredActionBar(true)
|
||||
.coloredStatusBar(true)
|
||||
.commit();
|
||||
ATE.config(this, VALUE_THEME_NAME_DARK)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE))
|
||||
.coloredActionBar(false)
|
||||
.coloredStatusBar(true)
|
||||
.statusBarColor(Color.BLACK)
|
||||
.commit();
|
||||
ATE.config(this, null)
|
||||
.accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK))
|
||||
.coloredActionBar(false)
|
||||
.coloredStatusBar(false)
|
||||
.commit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetTheme(SharedPreferences preferences) {
|
||||
switch (ThemeUtils.getLocalNightMode(preferences)) {
|
||||
case AppCompatDelegate.MODE_NIGHT_AUTO: {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
|
||||
break;
|
||||
}
|
||||
case AppCompatDelegate.MODE_NIGHT_YES: {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadDnsSettings() {
|
||||
DependencyHolder holder = DependencyHolder.get(this);
|
||||
final TwidereDns dns = holder.getDns();
|
||||
dns.reloadDnsSettings();
|
||||
}
|
||||
|
||||
|
||||
private void initializeAsyncTask() {
|
||||
// AsyncTask class needs to be loaded in UI thread.
|
||||
// So we load it here to comply the rule.
|
||||
try {
|
||||
Class.forName(AsyncTask.class.getName());
|
||||
} catch (final ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TwidereApplication getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
}
|
@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.app
|
||||
|
||||
import android.app.Application
|
||||
import android.content.*
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import android.content.pm.PackageManager
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.graphics.Color
|
||||
import android.os.AsyncTask
|
||||
import android.os.Handler
|
||||
import android.support.design.widget.FloatingActionButton
|
||||
import android.support.multidex.MultiDex
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.widget.SwipeRefreshLayout
|
||||
import android.support.v7.app.AppCompatDelegate
|
||||
import android.support.v7.widget.ActionBarContextView
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.afollestad.appthemeengine.ATE
|
||||
import com.afollestad.appthemeengine.Config
|
||||
import com.pnikosis.materialishprogress.ProgressWheel
|
||||
import com.rengwuxian.materialedittext.MaterialEditText
|
||||
import org.apache.commons.lang3.ArrayUtils
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.activity.AssistLauncherActivity
|
||||
import org.mariotaku.twidere.activity.MainActivity
|
||||
import org.mariotaku.twidere.activity.MainHondaJOJOActivity
|
||||
import org.mariotaku.twidere.service.RefreshService
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper
|
||||
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
||||
import org.mariotaku.twidere.util.theme.*
|
||||
import org.mariotaku.twidere.view.ProfileImageView
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator
|
||||
import org.mariotaku.twidere.view.ThemedMultiValueSwitch
|
||||
import org.mariotaku.twidere.view.TimelineContentTextView
|
||||
|
||||
class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeListener {
|
||||
|
||||
var handler: Handler? = null
|
||||
private set
|
||||
private var mPreferences: SharedPreferences? = null
|
||||
private var mSQLiteOpenHelper: SQLiteOpenHelper? = null
|
||||
|
||||
private var profileImageViewViewProcessor: ProfileImageViewViewProcessor? = null
|
||||
private var fontFamilyTagProcessor: FontFamilyTagProcessor? = null
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
MultiDex.install(this)
|
||||
}
|
||||
|
||||
fun initKeyboardShortcuts() {
|
||||
val preferences = sharedPreferences
|
||||
if (!preferences.getBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, false)) {
|
||||
// getApplicationModule().getKeyboardShortcutsHandler().reset();
|
||||
preferences.edit().putBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, true).apply()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val sqLiteDatabase: SQLiteDatabase by lazy {
|
||||
StrictModeUtils.checkDiskIO()
|
||||
sqLiteOpenHelper.writableDatabase
|
||||
}
|
||||
|
||||
val sqLiteOpenHelper: SQLiteOpenHelper by lazy {
|
||||
TwidereSQLiteOpenHelper(this, Constants.DATABASES_NAME, Constants.DATABASES_VERSION)
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
instance = this
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictModeUtils.detectAllVmPolicy()
|
||||
}
|
||||
val preferences = sharedPreferences
|
||||
resetTheme(preferences)
|
||||
super.onCreate()
|
||||
|
||||
profileImageViewViewProcessor = ProfileImageViewViewProcessor()
|
||||
fontFamilyTagProcessor = FontFamilyTagProcessor()
|
||||
|
||||
ATE.registerViewProcessor(TabPagerIndicator::class.java, TabPagerIndicatorViewProcessor())
|
||||
ATE.registerViewProcessor(FloatingActionButton::class.java, FloatingActionButtonViewProcessor())
|
||||
ATE.registerViewProcessor(ActionBarContextView::class.java, ActionBarContextViewViewProcessor())
|
||||
ATE.registerViewProcessor(SwipeRefreshLayout::class.java, SwipeRefreshLayoutViewProcessor())
|
||||
ATE.registerViewProcessor(TimelineContentTextView::class.java, TimelineContentTextViewViewProcessor())
|
||||
ATE.registerViewProcessor(TextView::class.java, TextViewViewProcessor())
|
||||
ATE.registerViewProcessor(ImageView::class.java, ImageViewViewProcessor())
|
||||
ATE.registerViewProcessor(MaterialEditText::class.java, MaterialEditTextViewProcessor())
|
||||
ATE.registerViewProcessor(ProgressWheel::class.java, ProgressWheelViewProcessor())
|
||||
ATE.registerViewProcessor(ProfileImageView::class.java, profileImageViewViewProcessor!!)
|
||||
ATE.registerTagProcessor(OptimalLinkColorTagProcessor.TAG, OptimalLinkColorTagProcessor())
|
||||
ATE.registerTagProcessor(FontFamilyTagProcessor.TAG, fontFamilyTagProcessor!!)
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR,
|
||||
IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR))
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_ACTIVATED,
|
||||
IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_ACTIVATED))
|
||||
ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_DISABLED,
|
||||
IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_DISABLED))
|
||||
ATE.registerTagProcessor(ThemedMultiValueSwitch.PREFIX_TINT, ThemedMultiValueSwitch.TintTagProcessor())
|
||||
|
||||
|
||||
profileImageViewViewProcessor!!.setStyle(Utils.getProfileImageStyle(preferences))
|
||||
fontFamilyTagProcessor!!.setFontFamily(ThemeUtils.getThemeFontFamily(preferences))
|
||||
|
||||
val themeColor = preferences.getInt(KEY_THEME_COLOR, ContextCompat.getColor(this,
|
||||
R.color.branding_color))
|
||||
if (!ATE.config(this, VALUE_THEME_NAME_LIGHT).isConfigured) {
|
||||
//noinspection WrongConstant
|
||||
ATE.config(this, VALUE_THEME_NAME_LIGHT).primaryColor(themeColor).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK)).coloredActionBar(true).coloredStatusBar(true).commit()
|
||||
}
|
||||
if (!ATE.config(this, VALUE_THEME_NAME_DARK).isConfigured) {
|
||||
ATE.config(this, VALUE_THEME_NAME_DARK).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE)).coloredActionBar(false).coloredStatusBar(true).statusBarColor(Color.BLACK).commit()
|
||||
}
|
||||
if (!ATE.config(this, null).isConfigured) {
|
||||
ATE.config(this, null).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE)).coloredActionBar(false).coloredStatusBar(false).commit()
|
||||
}
|
||||
initializeAsyncTask()
|
||||
initDebugMode()
|
||||
initBugReport()
|
||||
handler = Handler()
|
||||
|
||||
val pm = packageManager
|
||||
val main = ComponentName(this, MainActivity::class.java)
|
||||
val main2 = ComponentName(this, MainHondaJOJOActivity::class.java)
|
||||
val mainDisabled = pm.getComponentEnabledSetting(main) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
val main2Disabled = pm.getComponentEnabledSetting(main2) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
val noEntry = mainDisabled && main2Disabled
|
||||
if (noEntry) {
|
||||
pm.setComponentEnabledSetting(main, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP)
|
||||
} else if (!mainDisabled) {
|
||||
pm.setComponentEnabledSetting(main2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP)
|
||||
}
|
||||
if (!Utils.isComposeNowSupported(this)) {
|
||||
val assist = ComponentName(this, AssistLauncherActivity::class.java)
|
||||
pm.setComponentEnabledSetting(assist, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP)
|
||||
}
|
||||
|
||||
migrateUsageStatisticsPreferences()
|
||||
Utils.startRefreshServiceIfNeeded(this)
|
||||
|
||||
val holder = DependencyHolder.get(this)
|
||||
registerActivityLifecycleCallbacks(holder.activityTracker)
|
||||
|
||||
val packageFilter = IntentFilter()
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED)
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED)
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED)
|
||||
packageFilter.addAction(Intent.ACTION_PACKAGE_REPLACED)
|
||||
registerReceiver(object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val uid = intent.getIntExtra(Intent.EXTRA_UID, -1)
|
||||
val packages = packageManager.getPackagesForUid(uid)
|
||||
val holder = DependencyHolder.get(context)
|
||||
val manager = holder.externalThemeManager
|
||||
if (ArrayUtils.contains(packages, manager.emojiPackageName)) {
|
||||
manager.reloadEmojiPreferences()
|
||||
}
|
||||
}
|
||||
}, packageFilter)
|
||||
}
|
||||
|
||||
private fun initDebugMode() {
|
||||
DebugModeUtils.initForApplication(this)
|
||||
}
|
||||
|
||||
private fun initBugReport() {
|
||||
val preferences = sharedPreferences
|
||||
if (!preferences.getBoolean(KEY_BUG_REPORTS, BuildConfig.DEBUG)) return
|
||||
BugReporter.setImplementation(TwidereBugReporter())
|
||||
BugReporter.init(this)
|
||||
}
|
||||
|
||||
private fun migrateUsageStatisticsPreferences() {
|
||||
val preferences = sharedPreferences
|
||||
val hasUsageStatistics = preferences.contains(Constants.KEY_USAGE_STATISTICS)
|
||||
if (hasUsageStatistics) return
|
||||
if (preferences.contains(KEY_UCD_DATA_PROFILING) || preferences.contains(KEY_SPICE_DATA_PROFILING)) {
|
||||
val prevUsageEnabled = preferences.getBoolean(KEY_UCD_DATA_PROFILING, false) || preferences.getBoolean(KEY_SPICE_DATA_PROFILING, false)
|
||||
val editor = preferences.edit()
|
||||
editor.putBoolean(Constants.KEY_USAGE_STATISTICS, prevUsageEnabled)
|
||||
editor.remove(KEY_UCD_DATA_PROFILING)
|
||||
editor.remove(KEY_SPICE_DATA_PROFILING)
|
||||
editor.apply()
|
||||
}
|
||||
}
|
||||
|
||||
private val sharedPreferences: SharedPreferences by lazy {
|
||||
val prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
|
||||
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||
prefs
|
||||
}
|
||||
|
||||
override fun onTrimMemory(level: Int) {
|
||||
super.onTrimMemory(level)
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
val holder = DependencyHolder.get(this)
|
||||
super.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
||||
when (key) {
|
||||
KEY_REFRESH_INTERVAL -> {
|
||||
stopService(Intent(this, RefreshService::class.java))
|
||||
Utils.startRefreshServiceIfNeeded(this)
|
||||
}
|
||||
KEY_ENABLE_PROXY, KEY_PROXY_HOST, KEY_PROXY_PORT, KEY_PROXY_TYPE, KEY_PROXY_USERNAME, KEY_PROXY_PASSWORD, KEY_CONNECTION_TIMEOUT, KEY_RETRY_ON_NETWORK_ISSUE -> {
|
||||
HttpClientFactory.reloadConnectivitySettings(this)
|
||||
}
|
||||
KEY_DNS_SERVER, KEY_TCP_DNS_QUERY, KEY_BUILTIN_DNS_RESOLVER -> {
|
||||
reloadDnsSettings()
|
||||
}
|
||||
KEY_CONSUMER_KEY, KEY_CONSUMER_SECRET, KEY_API_URL_FORMAT, KEY_AUTH_TYPE, KEY_SAME_OAUTH_SIGNING_URL, KEY_THUMBOR_ENABLED, KEY_THUMBOR_ADDRESS, KEY_THUMBOR_SECURITY_KEY -> {
|
||||
val editor = preferences.edit()
|
||||
editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis())
|
||||
editor.apply()
|
||||
}
|
||||
KEY_EMOJI_SUPPORT -> {
|
||||
DependencyHolder.get(this).externalThemeManager.reloadEmojiPreferences()
|
||||
}
|
||||
KEY_THEME -> {
|
||||
resetTheme(preferences)
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK)
|
||||
}
|
||||
KEY_THEME_BACKGROUND -> {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK)
|
||||
}
|
||||
KEY_PROFILE_IMAGE_STYLE -> {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK)
|
||||
profileImageViewViewProcessor!!.setStyle(Utils.getProfileImageStyle(preferences.getString(key, null)))
|
||||
}
|
||||
KEY_THEME_FONT_FAMILY -> {
|
||||
Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK)
|
||||
fontFamilyTagProcessor!!.setFontFamily(ThemeUtils.getThemeFontFamily(preferences))
|
||||
}
|
||||
KEY_THEME_COLOR -> {
|
||||
val themeColor = preferences.getInt(key, ContextCompat.getColor(this,
|
||||
R.color.branding_color))
|
||||
//noinspection WrongConstant
|
||||
ATE.config(this, VALUE_THEME_NAME_LIGHT).primaryColor(themeColor).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK)).coloredActionBar(true).coloredStatusBar(true).commit()
|
||||
ATE.config(this, VALUE_THEME_NAME_DARK).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.WHITE)).coloredActionBar(false).coloredStatusBar(true).statusBarColor(Color.BLACK).commit()
|
||||
ATE.config(this, null).accentColor(ThemeUtils.getOptimalAccentColor(themeColor, Color.BLACK)).coloredActionBar(false).coloredStatusBar(false).commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetTheme(preferences: SharedPreferences) {
|
||||
when (ThemeUtils.getLocalNightMode(preferences)) {
|
||||
AppCompatDelegate.MODE_NIGHT_AUTO -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO)
|
||||
}
|
||||
AppCompatDelegate.MODE_NIGHT_YES -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
}
|
||||
else -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadDnsSettings() {
|
||||
val holder = DependencyHolder.get(this)
|
||||
val dns = holder.dns
|
||||
dns.reloadDnsSettings()
|
||||
}
|
||||
|
||||
|
||||
private fun initializeAsyncTask() {
|
||||
// AsyncTask class needs to be loaded in UI thread.
|
||||
// So we load it here to comply the rule.
|
||||
try {
|
||||
Class.forName(AsyncTask::class.java.name)
|
||||
} catch (ignore: ClassNotFoundException) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val KEY_UCD_DATA_PROFILING = "ucd_data_profiling"
|
||||
private val KEY_SPICE_DATA_PROFILING = "spice_data_profiling"
|
||||
private val KEY_KEYBOARD_SHORTCUT_INITIALIZED = "keyboard_shortcut_initialized"
|
||||
var instance: TwidereApplication? = null
|
||||
private set
|
||||
|
||||
fun getInstance(context: Context): TwidereApplication {
|
||||
return context.applicationContext as TwidereApplication
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentActivity
|
||||
import android.support.v4.view.ViewPager
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
@ -29,7 +28,6 @@ import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
||||
import org.mariotaku.twidere.view.ExtendedLinearLayout
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator
|
||||
|
||||
/**
|
||||
@ -38,33 +36,29 @@ import org.mariotaku.twidere.view.TabPagerIndicator
|
||||
abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScrollTopInterface, SupportFragmentCallback, IBaseFragment.SystemWindowsInsetsCallback, ControlBarOffsetListener, HideUiOnScroll, OnPageChangeListener, IToolBarSupportFragment, KeyboardShortcutCallback {
|
||||
|
||||
private var pagerAdapter: SupportTabsAdapter? = null
|
||||
private var mPagerIndicator: TabPagerIndicator? = null
|
||||
private var mViewPager: ViewPager? = null
|
||||
private var mWindowOverlay: View? = null
|
||||
override val toolbar: Toolbar
|
||||
get() = toolbarContainer.toolbar
|
||||
private var mControlBarHeight: Int = 0
|
||||
private var mToolbarContainer: ExtendedLinearLayout? = null
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
val activity = activity
|
||||
pagerAdapter = SupportTabsAdapter(activity, childFragmentManager, null, 1)
|
||||
mViewPager!!.adapter = pagerAdapter
|
||||
mViewPager!!.offscreenPageLimit = 2
|
||||
mViewPager!!.addOnPageChangeListener(this)
|
||||
mPagerIndicator!!.setViewPager(mViewPager)
|
||||
mPagerIndicator!!.setTabDisplayOption(TabPagerIndicator.LABEL)
|
||||
viewPager.adapter = pagerAdapter
|
||||
viewPager.offscreenPageLimit = 2
|
||||
viewPager.addOnPageChangeListener(this)
|
||||
toolbarTabs.setViewPager(viewPager)
|
||||
toolbarTabs.setTabDisplayOption(TabPagerIndicator.LABEL)
|
||||
|
||||
|
||||
addTabs(pagerAdapter!!)
|
||||
mToolbarContainer!!.setOnSizeChangedListener { view, w, h, oldw, oldh ->
|
||||
val pageLimit = mViewPager!!.offscreenPageLimit
|
||||
val currentItem = mViewPager!!.currentItem
|
||||
toolbarContainer.setOnSizeChangedListener { view, w, h, oldw, oldh ->
|
||||
val pageLimit = viewPager.offscreenPageLimit
|
||||
val currentItem = viewPager.currentItem
|
||||
val count = pagerAdapter!!.count
|
||||
for (i in 0..count - 1) {
|
||||
if (i > currentItem - pageLimit - 1 || i < currentItem + pageLimit) {
|
||||
val obj = pagerAdapter!!.instantiateItem(mViewPager, i)
|
||||
val obj = pagerAdapter!!.instantiateItem(viewPager, i)
|
||||
if (obj is IBaseFragment) {
|
||||
obj.requestFitSystemWindows()
|
||||
}
|
||||
@ -75,11 +69,6 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
|
||||
protected abstract fun addTabs(adapter: SupportTabsAdapter)
|
||||
|
||||
override fun onDestroy() {
|
||||
mViewPager!!.removeOnPageChangeListener(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onAttach(context: Context?) {
|
||||
super.onAttach(context)
|
||||
if (context is IControlBarActivity) {
|
||||
@ -101,10 +90,6 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
|
||||
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mViewPager = view!!.findViewById(R.id.view_pager) as ViewPager
|
||||
mToolbarContainer = view.findViewById(R.id.toolbarContainer) as ExtendedLinearLayout
|
||||
mPagerIndicator = view.findViewById(R.id.toolbarTabs) as TabPagerIndicator
|
||||
mWindowOverlay = view.findViewById(R.id.window_overlay)
|
||||
|
||||
val host = host
|
||||
if (host is AppCompatActivity) {
|
||||
@ -113,7 +98,7 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
val o = pagerAdapter!!.instantiateItem(mViewPager, mViewPager!!.currentItem)
|
||||
val o = pagerAdapter!!.instantiateItem(viewPager, viewPager.currentItem)
|
||||
if (o is Fragment) {
|
||||
o.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
@ -131,9 +116,9 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
}
|
||||
|
||||
override fun getCurrentVisibleFragment(): Fragment? {
|
||||
val currentItem = mViewPager!!.currentItem
|
||||
val currentItem = viewPager.currentItem
|
||||
if (currentItem < 0 || currentItem >= pagerAdapter!!.count) return null
|
||||
return pagerAdapter!!.instantiateItem(mViewPager, currentItem) as Fragment
|
||||
return pagerAdapter!!.instantiateItem(viewPager, currentItem) as Fragment
|
||||
}
|
||||
|
||||
override fun triggerRefresh(position: Int): Boolean {
|
||||
@ -144,8 +129,8 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
}
|
||||
|
||||
override fun getSystemWindowsInsets(insets: Rect): Boolean {
|
||||
if (mPagerIndicator == null) return false
|
||||
insets.set(0, mToolbarContainer!!.height, 0, 0)
|
||||
if (toolbarTabs == null) return false
|
||||
insets.set(0, toolbarContainer.height, 0, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -170,14 +155,14 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
|
||||
override var controlBarOffset: Float
|
||||
get() {
|
||||
if (mToolbarContainer == null) return 0f
|
||||
return 1 + mToolbarContainer!!.translationY / controlBarHeight
|
||||
if (toolbarContainer == null) return 0f
|
||||
return 1 + toolbarContainer.translationY / controlBarHeight
|
||||
}
|
||||
set(offset) {
|
||||
if (mToolbarContainer == null) return
|
||||
if (toolbarContainer == null) return
|
||||
val translationY = (offset - 1) * controlBarHeight
|
||||
mToolbarContainer!!.translationY = translationY
|
||||
mWindowOverlay!!.translationY = translationY
|
||||
toolbarContainer.translationY = translationY
|
||||
windowOverlay!!.translationY = translationY
|
||||
}
|
||||
|
||||
override val controlBarHeight: Int
|
||||
@ -193,16 +178,16 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
||||
if (action != null) {
|
||||
when (action) {
|
||||
ACTION_NAVIGATION_PREVIOUS_TAB -> {
|
||||
val previous = mViewPager!!.currentItem - 1
|
||||
val previous = viewPager.currentItem - 1
|
||||
if (previous >= 0 && previous < pagerAdapter!!.count) {
|
||||
mViewPager!!.setCurrentItem(previous, true)
|
||||
viewPager.setCurrentItem(previous, true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
ACTION_NAVIGATION_NEXT_TAB -> {
|
||||
val next = mViewPager!!.currentItem + 1
|
||||
val next = viewPager.currentItem + 1
|
||||
if (next >= 0 && next < pagerAdapter!!.count) {
|
||||
mViewPager!!.setCurrentItem(next, true)
|
||||
viewPager.setCurrentItem(next, true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -462,15 +462,15 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo
|
||||
}
|
||||
}
|
||||
final Menu menu = mNavigationView.getMenu();
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.interactions, !hasInteractionsTab);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.messages, !hasDmTab);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.interactions, !hasInteractionsTab);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.messages, !hasDmTab);
|
||||
|
||||
if (mUseStarsForLikes) {
|
||||
MenuUtils.setMenuItemTitle(menu, R.id.favorites, R.string.favorites);
|
||||
MenuUtils.setMenuItemIcon(menu, R.id.favorites, R.drawable.ic_action_star);
|
||||
MenuUtils.Companion.setMenuItemTitle(menu, R.id.favorites, R.string.favorites);
|
||||
MenuUtils.Companion.setMenuItemIcon(menu, R.id.favorites, R.drawable.ic_action_star);
|
||||
} else {
|
||||
MenuUtils.setMenuItemTitle(menu, R.id.favorites, R.string.likes);
|
||||
MenuUtils.setMenuItemIcon(menu, R.id.favorites, R.drawable.ic_action_heart);
|
||||
MenuUtils.Companion.setMenuItemTitle(menu, R.id.favorites, R.string.likes);
|
||||
MenuUtils.Companion.setMenuItemIcon(menu, R.id.favorites, R.drawable.ic_action_heart);
|
||||
}
|
||||
boolean hasLists = false, hasGroups = false, hasPublicTimeline = false;
|
||||
switch (ParcelableAccountUtils.getAccountType(account)) {
|
||||
@ -487,9 +487,9 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo
|
||||
break;
|
||||
}
|
||||
}
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.groups, hasGroups);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.lists, hasLists);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.public_timeline, hasPublicTimeline);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.groups, hasGroups);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.lists, hasLists);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.public_timeline, hasPublicTimeline);
|
||||
}
|
||||
|
||||
private boolean hasAccountInTab(SupportTabSpec tab, UserKey accountId, boolean isActivated) {
|
||||
|
@ -59,20 +59,20 @@ public class AddStatusFilterDialogFragment extends BaseDialogFragment {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
mFilterItems = getFilterItemsInfo();
|
||||
final String[] entries = new String[mFilterItems.length];
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST);
|
||||
for (int i = 0, j = entries.length; i < j; i++) {
|
||||
final FilterItemInfo info = mFilterItems[i];
|
||||
switch (info.type) {
|
||||
case FilterItemInfo.FILTER_TYPE_USER:
|
||||
entries[i] = getString(R.string.user_filter_name, getName(mUserColorNameManager,
|
||||
entries[i] = getString(R.string.user_filter_name, getName(userColorNameManager,
|
||||
info.value, nameFirst));
|
||||
break;
|
||||
case FilterItemInfo.FILTER_TYPE_KEYWORD:
|
||||
entries[i] = getString(R.string.keyword_filter_name, getName(mUserColorNameManager,
|
||||
entries[i] = getString(R.string.keyword_filter_name, getName(userColorNameManager,
|
||||
info.value, nameFirst));
|
||||
break;
|
||||
case FilterItemInfo.FILTER_TYPE_SOURCE:
|
||||
entries[i] = getString(R.string.source_filter_name, getName(mUserColorNameManager,
|
||||
entries[i] = getString(R.string.source_filter_name, getName(userColorNameManager,
|
||||
info.value, nameFirst));
|
||||
break;
|
||||
}
|
||||
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.DebugModeUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BaseDialogFragment extends DialogFragment implements Constants {
|
||||
|
||||
@Inject
|
||||
protected AsyncTwitterWrapper mTwitterWrapper;
|
||||
@Inject
|
||||
protected UserColorNameManager mUserColorNameManager;
|
||||
@Inject
|
||||
protected SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
protected TwidereValidator mValidator;
|
||||
@Inject
|
||||
protected KeyboardShortcutsHandler mKeyboardShortcutsHandler;
|
||||
|
||||
|
||||
public TwidereApplication getApplication() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return (TwidereApplication) activity.getApplication();
|
||||
return null;
|
||||
}
|
||||
|
||||
public ContentResolver getContentResolver() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getContentResolver();
|
||||
return null;
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences(final String name, final int mode) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSharedPreferences(name, mode);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getSystemService(final String name) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSystemService(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
DebugModeUtils.watchReferenceLeak(this);
|
||||
}
|
||||
|
||||
public void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
public void unregisterReceiver(final BroadcastReceiver receiver) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.unregisterReceiver(receiver);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.support.v4.app.DialogFragment
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.app.TwidereApplication
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
open class BaseDialogFragment : DialogFragment(), Constants {
|
||||
|
||||
@Inject
|
||||
lateinit var twitterWrapper: AsyncTwitterWrapper
|
||||
@Inject
|
||||
lateinit var userColorNameManager: UserColorNameManager
|
||||
@Inject
|
||||
lateinit var preferences: SharedPreferencesWrapper
|
||||
@Inject
|
||||
lateinit var validator: TwidereValidator
|
||||
@Inject
|
||||
lateinit var keyboardShortcutsHandler: KeyboardShortcutsHandler
|
||||
|
||||
|
||||
val application: TwidereApplication?
|
||||
get() {
|
||||
val activity = activity
|
||||
if (activity != null) return activity.application as TwidereApplication
|
||||
return null
|
||||
}
|
||||
|
||||
val contentResolver: ContentResolver
|
||||
get() = activity.contentResolver
|
||||
|
||||
fun getSystemService(name: String): Any? {
|
||||
val activity = activity
|
||||
if (activity != null) return activity.getSystemService(name)
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onAttach(context: Context?) {
|
||||
super.onAttach(context)
|
||||
GeneralComponentHelper.build(context!!).inject(this)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
DebugModeUtils.watchReferenceLeak(this)
|
||||
}
|
||||
|
||||
}
|
@ -118,7 +118,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
R.id.delete -> {
|
||||
val where = Expression.`in`(Column(Filters._ID),
|
||||
RawItemArray(listView.checkedItemIds))
|
||||
contentResolver!!.delete(contentUri, where.sql, null)
|
||||
contentResolver.delete(contentUri, where.sql, null)
|
||||
}
|
||||
R.id.inverse_selection -> {
|
||||
val positions = listView.getCheckedItemPositions()
|
||||
@ -347,7 +347,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
val resolver = contentResolver
|
||||
val where = Expression.equalsArgs(Filters.Users.USER_KEY).sql
|
||||
val whereArgs = arrayOf(user.key.toString())
|
||||
resolver!!.delete(Filters.Users.CONTENT_URI, where, whereArgs)
|
||||
resolver.delete(Filters.Users.CONTENT_URI, where, whereArgs)
|
||||
resolver.insert(Filters.Users.CONTENT_URI, values)
|
||||
}
|
||||
}
|
||||
@ -378,7 +378,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
|
||||
class FilterUsersListAdapter internal constructor(context: Context) : SimpleCursorAdapter(context, android.R.layout.simple_list_item_activated_2, null, arrayOfNulls<String>(0), IntArray(0), 0) {
|
||||
|
||||
private val mNameFirst: Boolean
|
||||
private val nameFirst: Boolean
|
||||
@Inject
|
||||
lateinit var userColorNameManager: UserColorNameManager
|
||||
@Inject
|
||||
@ -389,7 +389,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
|
||||
init {
|
||||
GeneralComponentHelper.build(context).inject(this)
|
||||
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true)
|
||||
nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true)
|
||||
}
|
||||
|
||||
override fun bindView(view: View, context: Context?, cursor: Cursor) {
|
||||
@ -400,7 +400,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
val name = cursor.getString(nameIdx)
|
||||
val screenName = cursor.getString(screenNameIdx)
|
||||
val displayName = userColorNameManager.getDisplayName(userId, name, screenName,
|
||||
mNameFirst)
|
||||
nameFirst)
|
||||
text1.text = displayName
|
||||
text2.text = userId.host
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class BaseListFragment extends ListFragment implements Constants, OnScrol
|
||||
}
|
||||
|
||||
public final TwidereApplication getApplication() {
|
||||
return TwidereApplication.getInstance(getActivity());
|
||||
return TwidereApplication.Companion.getInstance(getActivity());
|
||||
}
|
||||
|
||||
public final ContentResolver getContentResolver() {
|
||||
|
@ -73,9 +73,9 @@ open class BaseSupportFragment : Fragment(), IBaseFragment, Constants {
|
||||
GeneralComponentHelper.build(context!!).inject(this)
|
||||
}
|
||||
|
||||
val contentResolver: ContentResolver?
|
||||
val contentResolver: ContentResolver
|
||||
get() {
|
||||
return activity?.contentResolver
|
||||
return activity!!.contentResolver!!
|
||||
}
|
||||
|
||||
fun invalidateOptionsMenu() {
|
||||
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.iface.IDialogFragmentCallback;
|
||||
|
||||
import me.uucky.colorpicker.ColorPickerDialog;
|
||||
|
||||
public final class ColorPickerDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private ColorPickerDialog.Controller mController;
|
||||
|
||||
@Override
|
||||
public void onCancel(final DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
final FragmentActivity a = getActivity();
|
||||
if (a instanceof Callback) {
|
||||
((Callback) a).onCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
final FragmentActivity a = getActivity();
|
||||
if (!(a instanceof Callback) || mController == null) return;
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final int color = mController.getColor();
|
||||
((Callback) a).onColorSelected(color);
|
||||
break;
|
||||
}
|
||||
case DialogInterface.BUTTON_NEUTRAL: {
|
||||
((Callback) a).onColorCleared();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final int color;
|
||||
final Bundle args = getArguments();
|
||||
if (savedInstanceState != null) {
|
||||
color = savedInstanceState.getInt(EXTRA_COLOR, Color.WHITE);
|
||||
} else {
|
||||
color = args.getInt(EXTRA_COLOR, Color.WHITE);
|
||||
}
|
||||
|
||||
final FragmentActivity activity = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setView(me.uucky.colorpicker.R.layout.cp__dialog_color_picker);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
if (args.getBoolean(EXTRA_CLEAR_BUTTON, false)) {
|
||||
builder.setNeutralButton(R.string.clear, this);
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel, this);
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(DialogInterface di) {
|
||||
final Dialog dialog = (Dialog) di;
|
||||
mController = new ColorPickerDialog.Controller(dialog.getContext(), dialog.getWindow().getDecorView());
|
||||
|
||||
final boolean showAlphaSlider = args.getBoolean(EXTRA_ALPHA_SLIDER, true);
|
||||
for (int presetColor : PRESET_COLORS) {
|
||||
mController.addColor(ContextCompat.getColor(getContext(), presetColor));
|
||||
}
|
||||
mController.setAlphaEnabled(showAlphaSlider);
|
||||
mController.setInitialColor(color);
|
||||
}
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(final DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
final FragmentActivity a = getActivity();
|
||||
if (a instanceof Callback) {
|
||||
((Callback) a).onDismissed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(final Bundle outState) {
|
||||
if (mController != null) {
|
||||
outState.putInt(EXTRA_COLOR, mController.getColor());
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
public interface Callback extends IDialogFragmentCallback {
|
||||
|
||||
void onColorCleared();
|
||||
|
||||
void onColorSelected(int color);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.app.AlertDialog
|
||||
import me.uucky.colorpicker.ColorPickerDialog
|
||||
import org.mariotaku.twidere.Constants.*
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.fragment.iface.IDialogFragmentCallback
|
||||
|
||||
class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
private var mController: ColorPickerDialog.Controller? = null
|
||||
|
||||
override fun onCancel(dialog: DialogInterface?) {
|
||||
super.onCancel(dialog)
|
||||
val a = activity
|
||||
if (a is Callback) {
|
||||
a.onCancelled()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
val a = activity
|
||||
if (a !is Callback || mController == null) return
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val color = mController!!.color
|
||||
a.onColorSelected(color)
|
||||
}
|
||||
DialogInterface.BUTTON_NEUTRAL -> {
|
||||
a.onColorCleared()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val color: Int
|
||||
val args = arguments
|
||||
if (savedInstanceState != null) {
|
||||
color = savedInstanceState.getInt(EXTRA_COLOR, Color.WHITE)
|
||||
} else {
|
||||
color = args.getInt(EXTRA_COLOR, Color.WHITE)
|
||||
}
|
||||
|
||||
val activity = activity
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
builder.setView(me.uucky.colorpicker.R.layout.cp__dialog_color_picker)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
if (args.getBoolean(EXTRA_CLEAR_BUTTON, false)) {
|
||||
builder.setNeutralButton(R.string.clear, this)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel, this)
|
||||
val dialog = builder.create()
|
||||
dialog.setOnShowListener {
|
||||
it as Dialog
|
||||
mController = ColorPickerDialog.Controller(it.context, it.window.decorView)
|
||||
|
||||
val showAlphaSlider = args.getBoolean(EXTRA_ALPHA_SLIDER, true)
|
||||
for (presetColor in PRESET_COLORS) {
|
||||
mController!!.addColor(ContextCompat.getColor(context, presetColor))
|
||||
}
|
||||
mController!!.setAlphaEnabled(showAlphaSlider)
|
||||
mController!!.setInitialColor(color)
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface?) {
|
||||
super.onDismiss(dialog)
|
||||
val a = activity
|
||||
if (a is Callback) {
|
||||
a.onDismissed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
if (mController != null) {
|
||||
outState!!.putInt(EXTRA_COLOR, mController!!.color)
|
||||
}
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
interface Callback : IDialogFragmentCallback {
|
||||
|
||||
fun onColorCleared()
|
||||
|
||||
fun onColorSelected(color: Int)
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class CreateUserBlockDialogFragment extends BaseDialogFragment implements DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "create_user_block";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUser user = getUser();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (user == null || twitter == null) return;
|
||||
twitter.createBlockAsync(user.account_key, user.key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final Context context = activity;
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
final ParcelableUser user = getUser();
|
||||
if (user != null) {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, nameFirst);
|
||||
builder.setTitle(getString(R.string.block_user, displayName));
|
||||
builder.setMessage(getString(R.string.block_user_confirm_message, displayName));
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUser getUser() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER)) return null;
|
||||
return args.getParcelable(EXTRA_USER);
|
||||
}
|
||||
|
||||
public static CreateUserBlockDialogFragment show(final FragmentManager fm, final ParcelableUser user) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER, user);
|
||||
final CreateUserBlockDialogFragment f = new CreateUserBlockDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
|
||||
class CreateUserBlockDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val user = user
|
||||
val twitter = twitterWrapper
|
||||
if (user == null) return
|
||||
twitter.createBlockAsync(user.account_key, user.key)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val activity = activity
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val user = user
|
||||
if (user != null) {
|
||||
val nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
||||
val displayName = userColorNameManager.getDisplayName(user, nameFirst)
|
||||
builder.setTitle(getString(R.string.block_user, displayName))
|
||||
builder.setMessage(getString(R.string.block_user_confirm_message, displayName))
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val user: ParcelableUser?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USER)) return null
|
||||
return args.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "create_user_block"
|
||||
|
||||
fun show(fm: FragmentManager, user: ParcelableUser): CreateUserBlockDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER, user)
|
||||
val f = CreateUserBlockDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.rengwuxian.materialedittext.MaterialEditText;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.text.validator.UserListNameValidator;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
|
||||
public class CreateUserListDialogFragment extends BaseDialogFragment implements DialogInterface.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
final Bundle args = getArguments();
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
final MaterialEditText editName = (MaterialEditText) alertDialog.findViewById(R.id.name);
|
||||
final MaterialEditText editDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
|
||||
final CheckBox editPublic = (CheckBox) alertDialog.findViewById(R.id.is_public);
|
||||
assert editName != null && editDescription != null && editPublic != null;
|
||||
final String name = ParseUtils.parseString(editName.getText());
|
||||
final String description = ParseUtils.parseString(editDescription.getText());
|
||||
final boolean isPublic = editPublic.isChecked();
|
||||
if (TextUtils.isEmpty(name)) return;
|
||||
mTwitterWrapper.createUserListAsync(accountKey, name, isPublic, description);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setView(R.layout.dialog_user_list_detail_editor);
|
||||
|
||||
builder.setTitle(R.string.new_user_list);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, this);
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
final AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
MaterialEditText editName = (MaterialEditText) alertDialog.findViewById(R.id.name);
|
||||
MaterialEditText editDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
|
||||
CheckBox publicCheckBox = (CheckBox) alertDialog.findViewById(R.id.is_public);
|
||||
editName.addValidator(new UserListNameValidator(getString(R.string.invalid_list_name)));
|
||||
}
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.text.TextUtils
|
||||
import android.widget.CheckBox
|
||||
import com.rengwuxian.materialedittext.MaterialEditText
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.text.validator.UserListNameValidator
|
||||
import org.mariotaku.twidere.util.ParseUtils
|
||||
|
||||
class CreateUserListDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val alertDialog = dialog as AlertDialog
|
||||
val args = arguments
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val editName = alertDialog.findViewById(R.id.name) as MaterialEditText?
|
||||
val editDescription = alertDialog.findViewById(R.id.description) as MaterialEditText?
|
||||
val editPublic = alertDialog.findViewById(R.id.is_public) as CheckBox?
|
||||
assert(editName != null && editDescription != null && editPublic != null)
|
||||
val name = ParseUtils.parseString(editName!!.text)
|
||||
val description = ParseUtils.parseString(editDescription!!.text)
|
||||
val isPublic = editPublic!!.isChecked
|
||||
if (TextUtils.isEmpty(name)) return
|
||||
twitterWrapper.createUserListAsync(accountKey, name, isPublic, description)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setView(R.layout.dialog_user_list_detail_editor)
|
||||
|
||||
builder.setTitle(R.string.new_user_list)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, this)
|
||||
val dialog = builder.create()
|
||||
dialog.setOnShowListener { dialog ->
|
||||
val alertDialog = dialog as AlertDialog
|
||||
val editName = alertDialog.findViewById(R.id.name) as MaterialEditText?
|
||||
val editDescription = alertDialog.findViewById(R.id.description) as MaterialEditText?
|
||||
val publicCheckBox = alertDialog.findViewById(R.id.is_public) as CheckBox?
|
||||
editName!!.addValidator(UserListNameValidator(getString(R.string.invalid_list_name)))
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class CreateUserMuteDialogFragment extends BaseDialogFragment implements DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "create_user_mute";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUser user = getUser();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (user == null || twitter == null) return;
|
||||
twitter.createMuteAsync(user.account_key, user.key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final Context context = activity;
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
final ParcelableUser user = getUser();
|
||||
if (user != null) {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, nameFirst);
|
||||
builder.setTitle(getString(R.string.mute_user, displayName));
|
||||
builder.setMessage(getString(R.string.mute_user_confirm_message, displayName));
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUser getUser() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER)) return null;
|
||||
return args.getParcelable(EXTRA_USER);
|
||||
}
|
||||
|
||||
public static CreateUserMuteDialogFragment show(final FragmentManager fm, final ParcelableUser user) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER, user);
|
||||
final CreateUserMuteDialogFragment f = new CreateUserMuteDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
|
||||
class CreateUserMuteDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val user = user
|
||||
val twitter = twitterWrapper
|
||||
if (user == null) return
|
||||
twitter.createMuteAsync(user.account_key, user.key)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = context
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val user = user
|
||||
if (user != null) {
|
||||
val nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
||||
val displayName = userColorNameManager.getDisplayName(user, nameFirst)
|
||||
builder.setTitle(getString(R.string.mute_user, displayName))
|
||||
builder.setMessage(getString(R.string.mute_user_confirm_message, displayName))
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val user: ParcelableUser?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USER)) return null
|
||||
return args.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "create_user_mute"
|
||||
|
||||
fun show(fm: FragmentManager, user: ParcelableUser): CreateUserMuteDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER, user)
|
||||
val f = CreateUserMuteDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class DeleteUserListMembersDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "destroy_user_list_member";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUser[] users = getUsers();
|
||||
final ParcelableUserList userList = getUserList();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (users == null || userList == null || twitter == null) return;
|
||||
twitter.deleteUserListMembersAsync(userList.account_key, userList.id, users);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
final ParcelableUser[] users = getUsers();
|
||||
final ParcelableUserList userList = getUserList();
|
||||
if (users == null || userList == null) throw new NullPointerException();
|
||||
if (users.length == 1) {
|
||||
final ParcelableUser user = users[0];
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, nameFirst);
|
||||
builder.setTitle(getString(R.string.delete_user, displayName));
|
||||
builder.setMessage(getString(R.string.delete_user_from_list_confirm, displayName, userList.name));
|
||||
} else {
|
||||
builder.setTitle(R.string.delete_users);
|
||||
final Resources res = getResources();
|
||||
final String message = res.getQuantityString(R.plurals.delete_N_users_from_list_confirm, users.length,
|
||||
users.length, userList.name);
|
||||
builder.setMessage(message);
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUserList getUserList() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER_LIST)) return null;
|
||||
return args.getParcelable(EXTRA_USER_LIST);
|
||||
}
|
||||
|
||||
private ParcelableUser[] getUsers() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USERS)) return null;
|
||||
final Parcelable[] array = args.getParcelableArray(EXTRA_USERS);
|
||||
if (array == null) return null;
|
||||
final ParcelableUser[] users = new ParcelableUser[array.length];
|
||||
for (int i = 0, j = users.length; i < j; i++) {
|
||||
users[i] = (ParcelableUser) array[i];
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
public static DeleteUserListMembersDialogFragment show(final FragmentManager fm, final ParcelableUserList userList,
|
||||
final ParcelableUser... users) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER_LIST, userList);
|
||||
args.putParcelableArray(EXTRA_USERS, users);
|
||||
final DeleteUserListMembersDialogFragment f = new DeleteUserListMembersDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.ktextension.asTypedArray
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USERS
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER_LIST
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
import org.mariotaku.twidere.model.ParcelableUserList
|
||||
|
||||
class DeleteUserListMembersDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val users = users ?: return
|
||||
val userList = userList ?: return
|
||||
twitterWrapper.deleteUserListMembersAsync(userList.account_key, userList.id, *users)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val users = users
|
||||
val userList = userList
|
||||
if (users == null || userList == null) throw NullPointerException()
|
||||
if (users.size == 1) {
|
||||
val user = users[0]
|
||||
val nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
||||
val displayName = userColorNameManager.getDisplayName(user, nameFirst)
|
||||
builder.setTitle(getString(R.string.delete_user, displayName))
|
||||
builder.setMessage(getString(R.string.delete_user_from_list_confirm, displayName, userList.name))
|
||||
} else {
|
||||
builder.setTitle(R.string.delete_users)
|
||||
val res = resources
|
||||
val message = res.getQuantityString(R.plurals.delete_N_users_from_list_confirm, users.size,
|
||||
users.size, userList.name)
|
||||
builder.setMessage(message)
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val userList: ParcelableUserList?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USER_LIST)) return null
|
||||
return args.getParcelable<ParcelableUserList>(EXTRA_USER_LIST)
|
||||
}
|
||||
|
||||
private val users: Array<ParcelableUser>?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USERS)) return null
|
||||
return args.getParcelableArray(EXTRA_USERS)?.asTypedArray(ParcelableUser.CREATOR)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "destroy_user_list_member"
|
||||
|
||||
fun show(fm: FragmentManager, userList: ParcelableUserList,
|
||||
vararg users: ParcelableUser): DeleteUserListMembersDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER_LIST, userList)
|
||||
args.putParcelableArray(EXTRA_USERS, users)
|
||||
val f = DeleteUserListMembersDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class DestroyFriendshipDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "destroy_friendship";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUser user = getUser();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (user == null || twitter == null) return;
|
||||
twitter.destroyFriendshipAsync(user.account_key, user.key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final Context context = activity;
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
final ParcelableUser user = getUser();
|
||||
if (user != null) {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, nameFirst);
|
||||
builder.setTitle(getString(R.string.unfollow_user, displayName));
|
||||
builder.setMessage(getString(R.string.unfollow_user_confirm_message, displayName));
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUser getUser() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER)) return null;
|
||||
return args.getParcelable(EXTRA_USER);
|
||||
}
|
||||
|
||||
public static DestroyFriendshipDialogFragment show(final FragmentManager fm, final ParcelableUser user) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER, user);
|
||||
final DestroyFriendshipDialogFragment f = new DestroyFriendshipDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
|
||||
class DestroyFriendshipDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val user = user ?: return
|
||||
twitterWrapper.destroyFriendshipAsync(user.account_key, user.key)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
||||
val displayName = userColorNameManager.getDisplayName(user, nameFirst)
|
||||
builder.setTitle(getString(R.string.unfollow_user, displayName))
|
||||
builder.setMessage(getString(R.string.unfollow_user_confirm_message, displayName))
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val user: ParcelableUser?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(IntentConstants.EXTRA_USER)) return null
|
||||
return args.getParcelable<ParcelableUser>(IntentConstants.EXTRA_USER)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "destroy_friendship"
|
||||
|
||||
fun show(fm: FragmentManager, user: ParcelableUser): DestroyFriendshipDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(IntentConstants.EXTRA_USER, user)
|
||||
val f = DestroyFriendshipDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ public class DestroySavedSearchDialogFragment extends BaseDialogFragment impleme
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final UserKey accountKey = getAccountKey();
|
||||
final long searchId = getSearchId();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (searchId <= 0 || twitter == null) return;
|
||||
twitter.destroySavedSearchAsync(accountKey, searchId);
|
||||
break;
|
||||
|
@ -40,7 +40,7 @@ public class DestroyStatusDialogFragment extends BaseDialogFragment implements D
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableStatus status = getStatus();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (status == null || twitter == null) return;
|
||||
twitter.destroyStatusAsync(status.account_key, status.id);
|
||||
break;
|
||||
|
@ -40,7 +40,7 @@ public class DestroyUserListDialogFragment extends BaseDialogFragment implements
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUserList userList = getUserList();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (userList == null || twitter == null) return;
|
||||
twitter.destroyUserListAsync(userList.account_key, userList.id);
|
||||
break;
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class DestroyUserListSubscriptionDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "destroy_user_list";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUserList userList = getUserList();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (userList == null || twitter == null) return;
|
||||
twitter.destroyUserListSubscriptionAsync(userList.account_key, userList.id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
final ParcelableUserList userList = getUserList();
|
||||
if (userList != null) {
|
||||
builder.setTitle(getString(R.string.unsubscribe_from_user_list, userList.name));
|
||||
builder.setMessage(getString(R.string.unsubscribe_from_user_list_confirm_message, userList.name));
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUserList getUserList() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER_LIST)) return null;
|
||||
return args.getParcelable(EXTRA_USER_LIST);
|
||||
}
|
||||
|
||||
public static DestroyUserListSubscriptionDialogFragment show(final FragmentManager fm,
|
||||
final ParcelableUserList userList) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER_LIST, userList);
|
||||
final DestroyUserListSubscriptionDialogFragment f = new DestroyUserListSubscriptionDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER_LIST
|
||||
import org.mariotaku.twidere.model.ParcelableUserList
|
||||
|
||||
class DestroyUserListSubscriptionDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val userList = userList
|
||||
val twitter = twitterWrapper
|
||||
if (userList == null) return
|
||||
twitter.destroyUserListSubscriptionAsync(userList.account_key, userList.id)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val userList = userList
|
||||
if (userList != null) {
|
||||
builder.setTitle(getString(R.string.unsubscribe_from_user_list, userList.name))
|
||||
builder.setMessage(getString(R.string.unsubscribe_from_user_list_confirm_message, userList.name))
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val userList: ParcelableUserList?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USER_LIST)) return null
|
||||
return args.getParcelable<ParcelableUserList>(EXTRA_USER_LIST)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "destroy_user_list"
|
||||
|
||||
fun show(fm: FragmentManager,
|
||||
userList: ParcelableUserList): DestroyUserListSubscriptionDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER_LIST, userList)
|
||||
val f = DestroyUserListSubscriptionDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -1,404 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.ActionMode;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView.MultiChoiceModeListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.DraftsAdapter;
|
||||
import org.mariotaku.twidere.model.Draft;
|
||||
import org.mariotaku.twidere.model.DraftCursorIndices;
|
||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtra;
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
||||
import org.mariotaku.twidere.service.BackgroundOperationService;
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
|
||||
|
||||
public class DraftsFragment extends BaseSupportFragment implements LoaderCallbacks<Cursor>,
|
||||
OnItemClickListener, MultiChoiceModeListener {
|
||||
|
||||
private ContentResolver mResolver;
|
||||
|
||||
private DraftsAdapter mAdapter;
|
||||
|
||||
private ListView mListView;
|
||||
private View mEmptyView;
|
||||
private TextView mEmptyText;
|
||||
private ImageView mEmptyIcon;
|
||||
private View mListContainer, mProgressContainer;
|
||||
|
||||
private float mTextSize;
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
|
||||
mode.getMenuInflater().inflate(R.menu.action_multi_select_drafts, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
|
||||
updateTitle(mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.delete: {
|
||||
final DeleteDraftsConfirmDialogFragment f = new DeleteDraftsConfirmDialogFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putLongArray(EXTRA_IDS, mListView.getCheckedItemIds());
|
||||
f.setArguments(args);
|
||||
f.show(getChildFragmentManager(), "delete_drafts_confirm");
|
||||
break;
|
||||
}
|
||||
case R.id.send: {
|
||||
final Cursor c = mAdapter.getCursor();
|
||||
if (c == null || c.isClosed()) return false;
|
||||
final SparseBooleanArray checked = mListView.getCheckedItemPositions();
|
||||
final List<Draft> list = new ArrayList<>();
|
||||
final DraftCursorIndices indices = new DraftCursorIndices(c);
|
||||
for (int i = 0, j = checked.size(); i < j; i++) {
|
||||
if (checked.valueAt(i) && c.moveToPosition(checked.keyAt(i))) {
|
||||
list.add(indices.newObject(c));
|
||||
}
|
||||
}
|
||||
if (sendDrafts(list)) {
|
||||
final Expression where = Expression.in(new Column(Drafts._ID),
|
||||
new RawItemArray(mListView.getCheckedItemIds()));
|
||||
mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mode.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(final ActionMode mode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||
final Uri uri = Drafts.CONTENT_URI_UNSENT;
|
||||
final String[] cols = Drafts.COLUMNS;
|
||||
final String orderBy = Drafts.TIMESTAMP + " DESC";
|
||||
return new CursorLoader(getActivity(), uri, cols, null, null, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
|
||||
mAdapter.swapCursor(cursor);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<Cursor> loader) {
|
||||
mAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemCheckedStateChanged(final ActionMode mode, final int position, final long id,
|
||||
final boolean checked) {
|
||||
updateTitle(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(final AdapterView<?> view, final View child, final int position, final long id) {
|
||||
final Cursor c = mAdapter.getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return;
|
||||
final Draft item = DraftCursorIndices.fromCursor(c);
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
editDraft(item);
|
||||
return;
|
||||
}
|
||||
switch (item.action_type) {
|
||||
case "0":
|
||||
case "1":
|
||||
case Draft.Action.UPDATE_STATUS:
|
||||
case Draft.Action.REPLY:
|
||||
case Draft.Action.QUOTE: {
|
||||
editDraft(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_drafts, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mResolver = getContentResolver();
|
||||
mTextSize = preferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
||||
mAdapter = new DraftsAdapter(getActivity());
|
||||
mListView.setAdapter(mAdapter);
|
||||
mListView.setEmptyView(mEmptyView);
|
||||
mListView.setOnItemClickListener(this);
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
||||
mListView.setMultiChoiceModeListener(this);
|
||||
mEmptyIcon.setImageResource(R.drawable.ic_info_draft);
|
||||
mEmptyText.setText(R.string.drafts_hint_messages);
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (twitter != null) {
|
||||
twitter.clearNotificationAsync(NOTIFICATION_ID_DRAFTS);
|
||||
}
|
||||
super.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final float text_size = preferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
||||
mAdapter.setTextSize(text_size);
|
||||
if (mTextSize != text_size) {
|
||||
mTextSize = text_size;
|
||||
mListView.invalidateViews();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mListView = (ListView) view.findViewById(android.R.id.list);
|
||||
mEmptyView = view.findViewById(android.R.id.empty);
|
||||
mEmptyText = (TextView) view.findViewById(R.id.empty_text);
|
||||
mEmptyIcon = (ImageView) view.findViewById(R.id.empty_icon);
|
||||
mProgressContainer = view.findViewById(R.id.progress_container);
|
||||
mListContainer = view.findViewById(R.id.list_container);
|
||||
}
|
||||
|
||||
public void setListShown(boolean listShown) {
|
||||
mListContainer.setVisibility(listShown ? View.VISIBLE : View.GONE);
|
||||
mProgressContainer.setVisibility(listShown ? View.GONE : View.VISIBLE);
|
||||
mEmptyView.setVisibility(listShown && mAdapter.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void editDraft(final Draft draft) {
|
||||
final Intent intent = new Intent(INTENT_ACTION_EDIT_DRAFT);
|
||||
intent.putExtra(EXTRA_DRAFT, draft);
|
||||
mResolver.delete(Drafts.CONTENT_URI, Expression.equals(Drafts._ID, draft._id).getSQL(), null);
|
||||
startActivityForResult(intent, REQUEST_COMPOSE);
|
||||
}
|
||||
|
||||
private boolean sendDrafts(final List<Draft> list) {
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (twitter == null) return false;
|
||||
for (final Draft item : list) {
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
item.action_type = Draft.Action.UPDATE_STATUS;
|
||||
}
|
||||
switch (item.action_type) {
|
||||
case Draft.Action.UPDATE_STATUS_COMPAT_1:
|
||||
case Draft.Action.UPDATE_STATUS_COMPAT_2:
|
||||
case Draft.Action.UPDATE_STATUS:
|
||||
case Draft.Action.REPLY:
|
||||
case Draft.Action.QUOTE: {
|
||||
BackgroundOperationService.updateStatusesAsync(getContext(), item.action_type,
|
||||
ParcelableStatusUpdateUtils.fromDraftItem(getActivity(), item));
|
||||
break;
|
||||
}
|
||||
case Draft.Action.SEND_DIRECT_MESSAGE_COMPAT:
|
||||
case Draft.Action.SEND_DIRECT_MESSAGE: {
|
||||
String recipientId = null;
|
||||
if (item.action_extras instanceof SendDirectMessageActionExtra) {
|
||||
recipientId = ((SendDirectMessageActionExtra) item.action_extras).getRecipientId();
|
||||
}
|
||||
if (ArrayUtils.isEmpty(item.account_keys) || recipientId == null) {
|
||||
continue;
|
||||
}
|
||||
final UserKey accountId = item.account_keys[0];
|
||||
final String imageUri = item.media != null && item.media.length > 0 ? item.media[0].uri : null;
|
||||
twitter.sendDirectMessageAsync(accountId, recipientId, item.text, imageUri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateTitle(final ActionMode mode) {
|
||||
if (mListView == null || mode == null) return;
|
||||
final int count = mListView.getCheckedItemCount();
|
||||
mode.setTitle(getResources().getQuantityString(R.plurals.Nitems_selected, count, count));
|
||||
}
|
||||
|
||||
public static class DeleteDraftsConfirmDialogFragment extends BaseDialogFragment implements OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return;
|
||||
AsyncTaskUtils.executeTask(new DeleteDraftsTask(getActivity(), args.getLongArray(EXTRA_IDS)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(R.string.delete_drafts_confirm);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DeleteDraftsTask extends AsyncTask<Object, Object, Integer> {
|
||||
|
||||
private static final String FRAGMENT_TAG_DELETING_DRAFTS = "deleting_drafts";
|
||||
private final FragmentActivity mActivity;
|
||||
private final long[] mIds;
|
||||
private final NotificationManager mNotificationManager;
|
||||
private Handler mHandler;
|
||||
|
||||
private DeleteDraftsTask(final FragmentActivity activity, final long[] ids) {
|
||||
mActivity = activity;
|
||||
mNotificationManager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mIds = ids;
|
||||
mHandler = new Handler(activity.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(final Object... params) {
|
||||
final ContentResolver resolver = mActivity.getContentResolver();
|
||||
final Expression where = Expression.in(new Column(Drafts._ID), new RawItemArray(mIds));
|
||||
final String[] projection = {Drafts.MEDIA};
|
||||
final Cursor c = resolver.query(Drafts.CONTENT_URI, projection, where.getSQL(), null, null);
|
||||
if (c == null) return 0;
|
||||
final int idxMedia = c.getColumnIndex(Drafts.MEDIA);
|
||||
c.moveToFirst();
|
||||
while (!c.isAfterLast()) {
|
||||
final ParcelableMediaUpdate[] mediaArray = JsonSerializer.parseArray(c.getString(idxMedia),
|
||||
ParcelableMediaUpdate.class);
|
||||
if (mediaArray != null) {
|
||||
for (final ParcelableMediaUpdate media : mediaArray) {
|
||||
final Uri uri = Uri.parse(media.uri);
|
||||
if ("file".equals(uri.getScheme())) {
|
||||
final File file = new File(uri.getPath());
|
||||
if (!file.delete()) {
|
||||
Log.w(LOGTAG, String.format("Unable to delete %s", file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.moveToNext();
|
||||
}
|
||||
c.close();
|
||||
return resolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
final ProgressDialogFragment f = ProgressDialogFragment.show(mActivity,
|
||||
FRAGMENT_TAG_DELETING_DRAFTS);
|
||||
f.setCancelable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Integer result) {
|
||||
super.onPostExecute(result);
|
||||
final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS);
|
||||
if (f instanceof DialogFragment) {
|
||||
((DialogFragment) f).dismiss();
|
||||
}
|
||||
for (long id : mIds) {
|
||||
final String tag = Uri.withAppendedPath(Drafts.CONTENT_URI, String.valueOf(id)).toString();
|
||||
mNotificationManager.cancel(tag, NOTIFICATION_ID_DRAFTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.support.v4.app.DialogFragment
|
||||
import android.support.v4.app.FragmentActivity
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.CursorLoader
|
||||
import android.support.v4.content.Loader
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.AbsListView.MultiChoiceModeListener
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import android.widget.ListView
|
||||
import kotlinx.android.synthetic.main.fragment_drafts.*
|
||||
import org.apache.commons.lang3.ArrayUtils
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.adapter.DraftsAdapter
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.DraftCursorIndices
|
||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtra
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||
import org.mariotaku.twidere.service.BackgroundOperationService
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils
|
||||
import org.mariotaku.twidere.util.JsonSerializer
|
||||
import org.mariotaku.twidere.util.Utils.getDefaultTextSize
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor>, OnItemClickListener, MultiChoiceModeListener {
|
||||
|
||||
private var adapter: DraftsAdapter? = null
|
||||
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.action_multi_select_drafts, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
updateTitle(mode)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.delete -> {
|
||||
val f = DeleteDraftsConfirmDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putLongArray(IntentConstants.EXTRA_IDS, listView!!.checkedItemIds)
|
||||
f.arguments = args
|
||||
f.show(childFragmentManager, "delete_drafts_confirm")
|
||||
}
|
||||
R.id.send -> {
|
||||
val c = adapter!!.cursor
|
||||
if (c == null || c.isClosed) return false
|
||||
val checked = listView!!.checkedItemPositions
|
||||
val list = ArrayList<Draft>()
|
||||
val indices = DraftCursorIndices(c)
|
||||
var i = 0
|
||||
val j = checked.size()
|
||||
while (i < j) {
|
||||
if (checked.valueAt(i) && c.moveToPosition(checked.keyAt(i))) {
|
||||
list.add(indices.newObject(c))
|
||||
}
|
||||
i++
|
||||
}
|
||||
if (sendDrafts(list)) {
|
||||
val where = Expression.`in`(Column(Drafts._ID),
|
||||
RawItemArray(listView!!.checkedItemIds))
|
||||
contentResolver.delete(Drafts.CONTENT_URI, where.sql, null)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
mode.finish()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor> {
|
||||
val uri = Drafts.CONTENT_URI_UNSENT
|
||||
val cols = Drafts.COLUMNS
|
||||
val orderBy = Drafts.TIMESTAMP + " DESC"
|
||||
return CursorLoader(activity, uri, cols, null, null, orderBy)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
|
||||
adapter!!.swapCursor(cursor)
|
||||
setListShown(true)
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<Cursor>) {
|
||||
adapter!!.swapCursor(null)
|
||||
}
|
||||
|
||||
override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long,
|
||||
checked: Boolean) {
|
||||
updateTitle(mode)
|
||||
}
|
||||
|
||||
override fun onItemClick(view: AdapterView<*>, child: View, position: Int, id: Long) {
|
||||
val c = adapter!!.cursor
|
||||
if (c == null || c.isClosed || !c.moveToPosition(position)) return
|
||||
val item = DraftCursorIndices.fromCursor(c)
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
editDraft(item)
|
||||
return
|
||||
}
|
||||
when (item.action_type) {
|
||||
"0", "1", Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> {
|
||||
editDraft(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater!!.inflate(R.layout.fragment_drafts, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
adapter = DraftsAdapter(activity)
|
||||
adapter!!.setTextSize(preferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(activity)).toFloat())
|
||||
listView!!.adapter = adapter
|
||||
listView!!.emptyView = emptyView
|
||||
listView!!.onItemClickListener = this
|
||||
listView!!.choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL
|
||||
listView!!.setMultiChoiceModeListener(this)
|
||||
emptyIcon!!.setImageResource(R.drawable.ic_info_draft)
|
||||
emptyText!!.setText(R.string.drafts_hint_messages)
|
||||
loaderManager.initLoader(0, null, this)
|
||||
setListShown(false)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
twitterWrapper.clearNotificationAsync(NOTIFICATION_ID_DRAFTS)
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
fun setListShown(listShown: Boolean) {
|
||||
listContainer!!.visibility = if (listShown) View.VISIBLE else View.GONE
|
||||
progressContainer!!.visibility = if (listShown) View.GONE else View.VISIBLE
|
||||
emptyView!!.visibility = if (listShown && adapter!!.isEmpty) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun editDraft(draft: Draft) {
|
||||
val intent = Intent(INTENT_ACTION_EDIT_DRAFT)
|
||||
intent.putExtra(EXTRA_DRAFT, draft)
|
||||
contentResolver.delete(Drafts.CONTENT_URI, Expression.equals(Drafts._ID, draft._id).sql, null)
|
||||
startActivityForResult(intent, REQUEST_COMPOSE)
|
||||
}
|
||||
|
||||
private fun sendDrafts(list: List<Draft>): Boolean {
|
||||
loop@ for (item in list) {
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
item.action_type = Draft.Action.UPDATE_STATUS
|
||||
}
|
||||
when (item.action_type) {
|
||||
Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> {
|
||||
BackgroundOperationService.updateStatusesAsync(context, item.action_type,
|
||||
ParcelableStatusUpdateUtils.fromDraftItem(activity, item))
|
||||
}
|
||||
Draft.Action.SEND_DIRECT_MESSAGE_COMPAT, Draft.Action.SEND_DIRECT_MESSAGE -> {
|
||||
var recipientId: String? = null
|
||||
if (item.action_extras is SendDirectMessageActionExtra) {
|
||||
recipientId = (item.action_extras as SendDirectMessageActionExtra).recipientId
|
||||
}
|
||||
if (ArrayUtils.isEmpty(item.account_keys) || recipientId == null) {
|
||||
continue@loop
|
||||
}
|
||||
val accountId = item.account_keys!![0]
|
||||
val imageUri = if (item.media != null && item.media.size > 0) item.media[0].uri else null
|
||||
twitterWrapper.sendDirectMessageAsync(accountId, recipientId, item.text, imageUri)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun updateTitle(mode: ActionMode?) {
|
||||
if (listView == null || mode == null) return
|
||||
val count = listView!!.checkedItemCount
|
||||
mode.title = resources.getQuantityString(R.plurals.Nitems_selected, count, count)
|
||||
}
|
||||
|
||||
class DeleteDraftsConfirmDialogFragment : BaseDialogFragment(), OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val args = arguments ?: return
|
||||
AsyncTaskUtils.executeTask(DeleteDraftsTask(activity, args.getLongArray(IntentConstants.EXTRA_IDS)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setMessage(R.string.delete_drafts_confirm)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DeleteDraftsTask(
|
||||
private val activity: FragmentActivity,
|
||||
private val ids: LongArray
|
||||
) : AsyncTask<Any, Any, Int>() {
|
||||
private val notificationManager: NotificationManager
|
||||
private val handler: Handler
|
||||
|
||||
init {
|
||||
notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
handler = Handler(activity.mainLooper)
|
||||
}
|
||||
|
||||
override fun doInBackground(vararg params: Any): Int? {
|
||||
val resolver = activity.contentResolver
|
||||
val where = Expression.`in`(Column(Drafts._ID), RawItemArray(ids))
|
||||
val projection = arrayOf(Drafts.MEDIA)
|
||||
val c = resolver.query(Drafts.CONTENT_URI, projection, where.sql, null, null) ?: return 0
|
||||
val idxMedia = c.getColumnIndex(Drafts.MEDIA)
|
||||
c.moveToFirst()
|
||||
while (!c.isAfterLast) {
|
||||
val mediaArray = JsonSerializer.parseArray(c.getString(idxMedia), ParcelableMediaUpdate::class.java)
|
||||
if (mediaArray != null) {
|
||||
for (media in mediaArray) {
|
||||
val uri = Uri.parse(media.uri)
|
||||
if ("file" == uri.scheme) {
|
||||
val file = File(uri.path)
|
||||
if (!file.delete()) {
|
||||
Log.w(LOGTAG, String.format("Unable to delete %s", file))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.moveToNext()
|
||||
}
|
||||
c.close()
|
||||
return resolver.delete(Drafts.CONTENT_URI, where.sql, null)
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
val f = ProgressDialogFragment.show(activity, FRAGMENT_TAG_DELETING_DRAFTS)
|
||||
f.isCancelable = false
|
||||
}
|
||||
|
||||
override fun onPostExecute(result: Int?) {
|
||||
super.onPostExecute(result)
|
||||
val f = activity.supportFragmentManager.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS)
|
||||
if (f is DialogFragment) {
|
||||
f.dismiss()
|
||||
}
|
||||
for (id in ids) {
|
||||
val tag = Uri.withAppendedPath(Drafts.CONTENT_URI, id.toString()).toString()
|
||||
notificationManager.cancel(tag, NOTIFICATION_ID_DRAFTS)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val FRAGMENT_TAG_DELETING_DRAFTS = "deleting_drafts"
|
||||
}
|
||||
}
|
||||
}
|
@ -104,9 +104,9 @@ public class ExtensionsListFragment extends BaseListFragment implements LoaderCa
|
||||
if (extensionInfo.pname != null && extensionInfo.settings != null) {
|
||||
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_SETTINGS);
|
||||
intent.setClassName(extensionInfo.pname, extensionInfo.settings);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.settings, mPackageManager.queryIntentActivities(intent, 0).size() == 1);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.settings, mPackageManager.queryIntentActivities(intent, 0).size() == 1);
|
||||
} else {
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.settings, false);
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.settings, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ public class HostMappingsListFragment extends BaseListFragment implements MultiC
|
||||
final String host = ParseUtils.parseString(mEditHost.getText());
|
||||
final String address = mCheckExclude.isChecked() ? host : ParseUtils.parseString(mEditAddress.getText());
|
||||
if (isEmpty(host) || isEmpty(address)) return;
|
||||
final SharedPreferences prefs = getSharedPreferences(HOST_MAPPING_PREFERENCES_NAME,
|
||||
final SharedPreferences prefs = getContext().getSharedPreferences(HOST_MAPPING_PREFERENCES_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
final SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putString(host, address);
|
||||
|
@ -133,7 +133,7 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
mKeyboardShortcutsHandler.reset();
|
||||
keyboardShortcutsHandler.reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-6-24.
|
||||
*/
|
||||
public class MessageDialogFragment extends BaseDialogFragment {
|
||||
private static final String EXTRA_MESSAGE = "message";
|
||||
|
||||
public static MessageDialogFragment show(FragmentActivity activity, String message, String tag) {
|
||||
MessageDialogFragment df = new MessageDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(EXTRA_MESSAGE, message);
|
||||
df.setArguments(args);
|
||||
df.show(activity.getSupportFragmentManager(), tag);
|
||||
return df;
|
||||
}
|
||||
|
||||
public static MessageDialogFragment create(String message) {
|
||||
MessageDialogFragment df = new MessageDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(EXTRA_MESSAGE, message);
|
||||
df.setArguments(args);
|
||||
return df;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
FragmentActivity activity = getActivity();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
final Bundle args = getArguments();
|
||||
builder.setMessage(args.getString(EXTRA_MESSAGE));
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
return builder.create();
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentActivity
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-6-24.
|
||||
*/
|
||||
class MessageDialogFragment : BaseDialogFragment() {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val activity = activity
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
val args = arguments
|
||||
builder.setMessage(args.getString(EXTRA_MESSAGE))
|
||||
builder.setPositiveButton(android.R.string.ok, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EXTRA_MESSAGE = "message"
|
||||
|
||||
fun show(activity: FragmentActivity, message: String, tag: String): MessageDialogFragment {
|
||||
val df = MessageDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putString(EXTRA_MESSAGE, message)
|
||||
df.arguments = args
|
||||
df.show(activity.supportFragmentManager, tag)
|
||||
return df
|
||||
}
|
||||
|
||||
fun create(message: String): MessageDialogFragment {
|
||||
val df = MessageDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putString(EXTRA_MESSAGE, message)
|
||||
df.arguments = args
|
||||
return df
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,886 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.database.Cursor
|
||||
import android.os.AsyncTask
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.CursorLoader
|
||||
import android.support.v4.content.Loader
|
||||
import android.support.v4.view.ViewCompat
|
||||
import android.support.v7.app.ActionBar
|
||||
import android.support.v7.widget.FixedLinearLayoutManager
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.PopupMenu
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.text.Editable
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
import android.util.Property
|
||||
import android.view.*
|
||||
import android.view.View.OnClickListener
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemSelectedListener
|
||||
import android.widget.Toast
|
||||
import com.squareup.otto.Subscribe
|
||||
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
|
||||
import kotlinx.android.synthetic.main.layout_actionbar_message_user_picker.*
|
||||
import me.uucky.colorpicker.internal.EffectViewHelper
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.sqliteqb.library.OrderBy
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.activity.BaseActivity
|
||||
import org.mariotaku.twidere.activity.ThemedImagePickerActivity
|
||||
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter
|
||||
import org.mariotaku.twidere.adapter.MessageConversationAdapter
|
||||
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter
|
||||
import org.mariotaku.twidere.annotation.CustomTabType
|
||||
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.ACTION_NAVIGATION_BACK
|
||||
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants
|
||||
import org.mariotaku.twidere.loader.UserSearchLoader
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.message.TaskStateChangedEvent
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Conversation
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.TakeAllKeyboardShortcut
|
||||
import org.mariotaku.twidere.util.Utils.buildDirectMessageConversationUri
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import org.mariotaku.twidere.view.ExtendedRecyclerView
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MessagesConversationFragment : BaseSupportFragment(), LoaderCallbacks<Cursor>, OnClickListener, OnItemSelectedListener, PopupMenu.OnMenuItemClickListener, KeyboardShortcutCallback, TakeAllKeyboardShortcut {
|
||||
|
||||
|
||||
// Callbacks and listeners
|
||||
private val searchLoadersCallback = object : LoaderCallbacks<List<ParcelableUser>> {
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>> {
|
||||
usersSearchList!!.visibility = View.GONE
|
||||
usersSearchEmpty!!.visibility = View.GONE
|
||||
usersSearchProgress!!.visibility = View.VISIBLE
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val query = args.getString(EXTRA_QUERY)
|
||||
val fromCache = args.getBoolean(EXTRA_FROM_CACHE)
|
||||
val fromUser = args.getBoolean(EXTRA_FROM_USER, false)
|
||||
return CacheUserSearchLoader(this@MessagesConversationFragment, accountKey, query,
|
||||
fromCache, fromUser)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<List<ParcelableUser>>, data: List<ParcelableUser>?) {
|
||||
usersSearchList!!.visibility = View.VISIBLE
|
||||
usersSearchProgress!!.visibility = View.GONE
|
||||
usersSearchEmpty!!.visibility = if (data == null || data.isEmpty()) View.GONE else View.VISIBLE
|
||||
mUsersSearchAdapter!!.setData(data, true)
|
||||
updateEmptyText()
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<List<ParcelableUser>>) {
|
||||
|
||||
}
|
||||
}
|
||||
private var scrollListener: PanelShowHideListener? = null
|
||||
|
||||
private var messageDrafts: SharedPreferences? = null
|
||||
private var mEffectHelper: EffectViewHelper? = null
|
||||
|
||||
// Adapters
|
||||
private var mAdapter: MessageConversationAdapter? = null
|
||||
private var mUsersSearchAdapter: SimpleParcelableUsersAdapter? = null
|
||||
|
||||
// Data fields
|
||||
private var searchUsersLoaderInitialized: Boolean = false
|
||||
private var navigateBackPressed: Boolean = false
|
||||
private val selectedDirectMessage: ParcelableDirectMessage? = null
|
||||
private var loaderInitialized: Boolean = false
|
||||
private var imageUri: String? = null
|
||||
private var account: ParcelableCredentials? = null
|
||||
private var recipient: ParcelableUser? = null
|
||||
private var textChanged: Boolean = false
|
||||
private var queryTextChanged: Boolean = false
|
||||
|
||||
private val backTimeoutRunnable = Runnable { navigateBackPressed = false }
|
||||
|
||||
@Subscribe
|
||||
fun notifyTaskStateChanged(event: TaskStateChangedEvent) {
|
||||
updateRefreshState()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
REQUEST_PICK_IMAGE -> {
|
||||
if (resultCode == Activity.RESULT_OK && data!!.dataString != null) {
|
||||
imageUri = data.dataString
|
||||
updateAddImageButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater!!.inflate(R.layout.fragment_messages_conversation, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
val activity = activity as BaseActivity
|
||||
messageDrafts = activity.getSharedPreferences(MESSAGE_DRAFTS_PREFERENCES_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
val view = view!!
|
||||
val viewContext = view.context
|
||||
setHasOptionsMenu(true)
|
||||
val actionBar = activity.supportActionBar ?: throw NullPointerException()
|
||||
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
|
||||
ActionBar.DISPLAY_SHOW_TITLE or ActionBar.DISPLAY_SHOW_CUSTOM)
|
||||
actionBar.setCustomView(R.layout.layout_actionbar_message_user_picker)
|
||||
val accounts = DataStoreUtils.getCredentialsList(activity, false)
|
||||
val accountsSpinnerAdapter = AccountsSpinnerAdapter(
|
||||
actionBar.themedContext, R.layout.spinner_item_account_icon)
|
||||
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_user)
|
||||
accountsSpinnerAdapter.addAll(accounts)
|
||||
accountSpinner.adapter = accountsSpinnerAdapter
|
||||
accountSpinner.onItemSelectedListener = this
|
||||
queryButton.setOnClickListener(this)
|
||||
mAdapter = MessageConversationAdapter(activity)
|
||||
val layoutManager = FixedLinearLayoutManager(viewContext)
|
||||
layoutManager.orientation = LinearLayoutManager.VERTICAL
|
||||
layoutManager.stackFromEnd = true
|
||||
recyclerView.layoutManager = layoutManager
|
||||
recyclerView.adapter = mAdapter
|
||||
|
||||
val useOutline = Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
|
||||
|
||||
val effectHelper: EffectViewHelper
|
||||
if (useOutline) {
|
||||
val elevation = resources.getDimension(R.dimen.element_spacing_normal)
|
||||
val property = PanelElevationProperty(elevation)
|
||||
effectHelper = EffectViewHelper(inputPanel, property, 100)
|
||||
} else {
|
||||
effectHelper = EffectViewHelper(inputPanelShadowCompat, View.ALPHA, 100)
|
||||
}
|
||||
scrollListener = PanelShowHideListener(effectHelper)
|
||||
|
||||
inputPanelShadowCompat!!.visibility = if (useOutline) View.GONE else View.VISIBLE
|
||||
ViewCompat.setAlpha(inputPanelShadowCompat, 0f)
|
||||
|
||||
mUsersSearchAdapter = SimpleParcelableUsersAdapter(activity)
|
||||
usersSearchList!!.adapter = mUsersSearchAdapter
|
||||
usersSearchList!!.emptyView = usersSearchEmpty
|
||||
usersSearchList!!.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
|
||||
val account = accountSpinner.selectedItem as ParcelableCredentials
|
||||
showConversation(account, mUsersSearchAdapter!!.getItem(position))
|
||||
updateRecipientInfo()
|
||||
}
|
||||
|
||||
setupEditQuery()
|
||||
setupEditText()
|
||||
|
||||
send!!.setOnClickListener(this)
|
||||
addImage!!.setOnClickListener(this)
|
||||
send!!.isEnabled = false
|
||||
if (savedInstanceState != null) {
|
||||
val account = savedInstanceState.getParcelable<ParcelableCredentials>(EXTRA_ACCOUNT)
|
||||
val recipient = savedInstanceState.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
showConversation(account, recipient)
|
||||
editText.setText(savedInstanceState.getString(EXTRA_TEXT))
|
||||
imageUri = savedInstanceState.getString(EXTRA_IMAGE_URI)
|
||||
} else {
|
||||
val args = arguments
|
||||
val account: ParcelableCredentials?
|
||||
val recipient: ParcelableUser?
|
||||
if (args != null) {
|
||||
if (args.containsKey(EXTRA_ACCOUNT)) {
|
||||
account = args.getParcelable<ParcelableCredentials>(EXTRA_ACCOUNT)
|
||||
recipient = args.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
} else if (args.containsKey(EXTRA_ACCOUNT_KEY) && args.containsKey(EXTRA_RECIPIENT_ID)) {
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
if (accountKey == null) {
|
||||
getActivity().finish()
|
||||
return
|
||||
}
|
||||
val accountPos = accountsSpinnerAdapter.findPositionByKey(accountKey)
|
||||
if (accountPos >= 0) {
|
||||
accountSpinner.setSelection(accountPos)
|
||||
}
|
||||
val userId = args.getString(EXTRA_RECIPIENT_ID)
|
||||
if (accountPos >= 0) {
|
||||
account = accountsSpinnerAdapter.getItem(accountPos)
|
||||
} else {
|
||||
account = ParcelableCredentialsUtils.getCredentials(activity, accountKey)
|
||||
}
|
||||
if (userId != null) {
|
||||
recipient = Utils.getUserForConversation(activity, accountKey, userId)
|
||||
} else {
|
||||
recipient = null
|
||||
}
|
||||
} else {
|
||||
account = null
|
||||
recipient = null
|
||||
}
|
||||
showConversation(account, recipient)
|
||||
if (account != null && recipient != null) {
|
||||
val key = getDraftsTextKey(account.account_key, recipient.key)
|
||||
editText.setText(messageDrafts!!.getString(key, null))
|
||||
}
|
||||
}
|
||||
}
|
||||
editText.setSelection(editText.length())
|
||||
val isValid = account != null && recipient != null
|
||||
conversationContainer!!.visibility = if (isValid) View.VISIBLE else View.GONE
|
||||
recipientSelectorContainer!!.visibility = if (isValid) View.GONE else View.VISIBLE
|
||||
|
||||
usersSearchList!!.visibility = View.GONE
|
||||
usersSearchProgress!!.visibility = View.GONE
|
||||
|
||||
registerForContextMenu(recyclerView)
|
||||
|
||||
queryTextChanged = false
|
||||
textChanged = false
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
bus.register(this)
|
||||
updateEmptyText()
|
||||
recyclerView.addOnScrollListener(scrollListener)
|
||||
scrollListener!!.reset()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateAddImageButton()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (editText != null) {
|
||||
outState!!.putCharSequence(EXTRA_TEXT, editText.text)
|
||||
}
|
||||
outState!!.putParcelable(EXTRA_ACCOUNT, account)
|
||||
outState.putParcelable(EXTRA_USER, recipient)
|
||||
outState.putString(EXTRA_IMAGE_URI, imageUri)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
recyclerView.removeOnScrollListener(scrollListener)
|
||||
bus.unregister(this)
|
||||
|
||||
val account = account
|
||||
val recipient = recipient
|
||||
if (account != null && recipient != null) {
|
||||
val key = getDraftsTextKey(account.account_key, recipient.key)
|
||||
val editor = messageDrafts!!.edit()
|
||||
val text = ParseUtils.parseString(editText.text)
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
editor.remove(key)
|
||||
} else {
|
||||
editor.putString(key, text)
|
||||
}
|
||||
editor.apply()
|
||||
}
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater!!.inflate(R.menu.menu_direct_messages_conversation, menu)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.delete_all, recipient != null && Utils.isOfficialCredentials(activity, account!!))
|
||||
updateRecipientInfo()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item!!.itemId) {
|
||||
R.id.delete_all -> {
|
||||
val account = account
|
||||
if (account == null || recipient == null) return true
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_ACCOUNT, account)
|
||||
args.putParcelable(EXTRA_USER, recipient)
|
||||
val df = DeleteConversationConfirmDialogFragment()
|
||||
df.arguments = args
|
||||
df.show(fragmentManager, "delete_conversation_confirm")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
|
||||
val accountId = args?.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val recipientId = args?.getString(EXTRA_RECIPIENT_ID)
|
||||
val cols = DirectMessages.COLUMNS
|
||||
val isValid = accountId != null && recipientId != null
|
||||
conversationContainer!!.visibility = if (isValid) View.VISIBLE else View.GONE
|
||||
recipientSelectorContainer!!.visibility = if (isValid) View.GONE else View.VISIBLE
|
||||
if (!isValid) {
|
||||
return CursorLoader(activity, TwidereDataStore.CONTENT_URI_NULL, cols, null, null, null)
|
||||
}
|
||||
val uri = buildDirectMessageConversationUri(accountId, recipientId, null)
|
||||
return CursorLoader(activity, uri, cols, null, null, Conversation.DEFAULT_SORT_ORDER)
|
||||
}
|
||||
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.send -> {
|
||||
sendDirectMessage()
|
||||
}
|
||||
R.id.addImage -> {
|
||||
val intent = ThemedImagePickerActivity.withThemed(activity).build()
|
||||
startActivityForResult(intent, REQUEST_PICK_IMAGE)
|
||||
}
|
||||
R.id.queryButton -> {
|
||||
val account = accountSpinner.selectedItem as ParcelableCredentials
|
||||
searchUsers(account.account_key, ParseUtils.parseString(editUserQuery!!.text), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
|
||||
val account = accountSpinner.selectedItem as ParcelableCredentials?
|
||||
if (account != null) {
|
||||
this.account = account
|
||||
updateRecipientInfo()
|
||||
updateAccount()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(view: AdapterView<*>) {
|
||||
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<Cursor>) {
|
||||
mAdapter!!.setCursor(null)
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
val message = selectedDirectMessage
|
||||
if (message != null) {
|
||||
when (item.itemId) {
|
||||
R.id.delete -> {
|
||||
twitterWrapper.destroyDirectMessageAsync(message.account_key, message.id)
|
||||
}
|
||||
R.id.copy -> {
|
||||
if (ClipboardUtils.setText(activity, message.text_plain)) {
|
||||
Utils.showOkMessage(activity, R.string.text_copied, false)
|
||||
}
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
|
||||
mAdapter!!.setCursor(cursor)
|
||||
}
|
||||
|
||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
|
||||
if (menuInfo == null) return
|
||||
val inflater = MenuInflater(context)
|
||||
val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo?
|
||||
val message = mAdapter!!.getDirectMessage(contextMenuInfo!!.position)
|
||||
menu.setHeaderTitle(message.text_unescaped)
|
||||
inflater.inflate(R.menu.action_direct_message, menu)
|
||||
}
|
||||
|
||||
override fun onContextItemSelected(item: MenuItem?): Boolean {
|
||||
if (!userVisibleHint) return false
|
||||
val menuInfo = item!!.menuInfo
|
||||
val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo
|
||||
val message = mAdapter!!.getDirectMessage(contextMenuInfo.position) ?: return false
|
||||
when (item.itemId) {
|
||||
R.id.copy -> {
|
||||
ClipboardUtils.setText(context, message.text_plain)
|
||||
return true
|
||||
}
|
||||
R.id.delete -> {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_ACCOUNT, account)
|
||||
args.putParcelable(EXTRA_MESSAGE, message)
|
||||
val df = DeleteMessageConfirmDialogFragment()
|
||||
df.arguments = args
|
||||
df.show(fragmentManager, "delete_message_confirm")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
||||
val action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
||||
if (ACTION_NAVIGATION_BACK == action) {
|
||||
val showingConversation = isShowingConversation
|
||||
val editText = if (showingConversation) editText else editUserQuery
|
||||
val textChanged = if (showingConversation) textChanged else queryTextChanged
|
||||
if (editText.length() == 0 && !textChanged) {
|
||||
val activity = activity
|
||||
if (!navigateBackPressed) {
|
||||
Toast.makeText(activity, R.string.press_again_to_close, Toast.LENGTH_SHORT).show()
|
||||
editText.removeCallbacks(backTimeoutRunnable)
|
||||
editText.postDelayed(backTimeoutRunnable, 2000)
|
||||
navigateBackPressed = true
|
||||
} else {
|
||||
activity.onBackPressed()
|
||||
}
|
||||
} else {
|
||||
queryTextChanged = false
|
||||
this.textChanged = false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
||||
val action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
||||
return ACTION_NAVIGATION_BACK == action
|
||||
}
|
||||
|
||||
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int, repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
fun showConversation(account: ParcelableCredentials?, recipient: ParcelableUser?) {
|
||||
this.account = account
|
||||
this.recipient = recipient
|
||||
if (account == null || recipient == null) return
|
||||
val lm = loaderManager
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_ACCOUNT_KEY, account.account_key)
|
||||
args.putString(EXTRA_RECIPIENT_ID, recipient.key.id)
|
||||
if (loaderInitialized) {
|
||||
lm.restartLoader(0, args, this)
|
||||
} else {
|
||||
loaderInitialized = true
|
||||
lm.initLoader(0, args, this)
|
||||
}
|
||||
AsyncTaskUtils.executeTask(SetReadStateTask(activity, account, recipient))
|
||||
updateActionBar()
|
||||
updateRecipientInfo()
|
||||
updateAccount()
|
||||
editText.requestFocus()
|
||||
}
|
||||
|
||||
private fun updateAccount() {
|
||||
if (account == null) return
|
||||
if (Utils.isOfficialCredentials(context, account!!)) {
|
||||
addImage!!.visibility = View.VISIBLE
|
||||
} else {
|
||||
addImage!!.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val isShowingConversation: Boolean
|
||||
get() = conversationContainer!!.visibility == View.VISIBLE
|
||||
|
||||
private fun getDraftsTextKey(accountKey: UserKey, userId: UserKey): String {
|
||||
return String.format(Locale.ROOT, "text_%s_to_%s", accountKey, userId)
|
||||
}
|
||||
|
||||
private fun searchUsers(accountKey: UserKey, query: String, fromCache: Boolean) {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey)
|
||||
args.putString(EXTRA_QUERY, query)
|
||||
args.putBoolean(EXTRA_FROM_CACHE, fromCache)
|
||||
val lm = loaderManager
|
||||
if (searchUsersLoaderInitialized) {
|
||||
lm.restartLoader(LOADER_ID_SEARCH_USERS, args, searchLoadersCallback)
|
||||
} else {
|
||||
searchUsersLoaderInitialized = true
|
||||
lm.initLoader(LOADER_ID_SEARCH_USERS, args, searchLoadersCallback)
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onRefreshFromEnd() {
|
||||
// new TwidereAsyncTask<Object, Object, long[][]>() {
|
||||
//
|
||||
// @Override
|
||||
// protected long[][] doInBackground(final Object... params) {
|
||||
// final long[][] result = new long[2][];
|
||||
// result[0] = getActivatedAccountIds(getActivity());
|
||||
// result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onPostExecute(final long[][] result) {
|
||||
// final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
// if (twitter == null) return;
|
||||
// twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
|
||||
// twitter.getSentDirectMessagesAsync(result[0], null, null);
|
||||
// }
|
||||
//
|
||||
// }.executeTask();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onRefresh() {
|
||||
// loadMoreMessages();
|
||||
// }
|
||||
|
||||
private fun sendDirectMessage() {
|
||||
val account = account ?: return
|
||||
val recipient = recipient ?: return
|
||||
val message = editText.text.toString()
|
||||
if (TextUtils.isEmpty(message)) {
|
||||
editText.error = getString(R.string.error_message_no_content)
|
||||
} else {
|
||||
twitterWrapper.sendDirectMessageAsync(account.account_key, recipient.key.id,
|
||||
message, imageUri)
|
||||
editText.text = null
|
||||
imageUri = null
|
||||
updateAddImageButton()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupEditQuery() {
|
||||
val queryEnterHandler = EditTextEnterHandler.attach(editUserQuery!!, object : EnterListener {
|
||||
override fun shouldCallListener(): Boolean {
|
||||
val activity = activity
|
||||
if (activity !is BaseActivity) return false
|
||||
return activity.keyMetaState == 0
|
||||
}
|
||||
|
||||
override fun onHitEnter(): Boolean {
|
||||
val activity = activity
|
||||
if (activity !is BaseActivity) return false
|
||||
if (activity.keyMetaState != 0) return false
|
||||
val account = accountSpinner.selectedItem as ParcelableCredentials ?: return false
|
||||
editText.setAccountKey(account.account_key)
|
||||
searchUsers(account.account_key, ParseUtils.parseString(editUserQuery!!.text), false)
|
||||
return true
|
||||
}
|
||||
}, true)
|
||||
queryEnterHandler.addTextChangedListener(object : TextWatcher {
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val account = accountSpinner.selectedItem as ParcelableCredentials ?: return
|
||||
editText.setAccountKey(account.account_key)
|
||||
searchUsers(account.account_key, ParseUtils.parseString(s), true)
|
||||
}
|
||||
})
|
||||
editUserQuery!!.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
// Utils.removeLineBreaks(s);
|
||||
queryTextChanged = s.length == 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setupEditText() {
|
||||
EditTextEnterHandler.attach(editText, object : EnterListener {
|
||||
override fun shouldCallListener(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onHitEnter(): Boolean {
|
||||
sendDirectMessage()
|
||||
return true
|
||||
}
|
||||
}, preferences.getBoolean(SharedPreferenceConstants.KEY_QUICK_SEND, false))
|
||||
editText.addTextChangedListener(object : TextWatcher {
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
textChanged = s.length == 0
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
if (send == null || s == null) return
|
||||
send!!.isEnabled = validator.isValidDirectMessage(s.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun updateActionBar() {
|
||||
val activity = activity as BaseActivity
|
||||
val actionBar = activity.supportActionBar ?: return
|
||||
actionBar.setDisplayOptions(if (recipient != null) ActionBar.DISPLAY_SHOW_TITLE else ActionBar.DISPLAY_SHOW_CUSTOM,
|
||||
ActionBar.DISPLAY_SHOW_TITLE or ActionBar.DISPLAY_SHOW_CUSTOM)
|
||||
}
|
||||
|
||||
private fun updateAddImageButton() {
|
||||
addImage!!.isActivated = imageUri != null
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean scrollToStart() {
|
||||
// if (mAdapter == null || mAdapter.isEmpty()) return false;
|
||||
// setSelection(mAdapter.getCount() - 1);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
private fun updateEmptyText() {
|
||||
val noQuery = editUserQuery!!.length() <= 0
|
||||
if (noQuery) {
|
||||
usersSearchEmptyText!!.setText(R.string.type_name_to_search)
|
||||
} else {
|
||||
usersSearchEmptyText!!.setText(R.string.no_user_found)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRecipientInfo() {
|
||||
val activity = activity ?: return
|
||||
if (recipient != null) {
|
||||
activity.title = userColorNameManager.getDisplayName(recipient,
|
||||
preferences.getBoolean(KEY_NAME_FIRST))
|
||||
} else {
|
||||
activity.setTitle(R.string.direct_messages)
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void onReachedTop() {
|
||||
// if (!mLoadMoreAutomatically) return;
|
||||
// loadMoreMessages();
|
||||
// }
|
||||
|
||||
private fun updateRefreshState() {
|
||||
// final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
// if (twitter == null || !getUserVisibleHint()) return;
|
||||
// final boolean refreshing = twitter.isReceivedDirectMessagesRefreshing()
|
||||
// || twitter.isSentDirectMessagesRefreshing();
|
||||
// setRefreshing(refreshing);
|
||||
}
|
||||
|
||||
// private void loadMoreMessages() {
|
||||
// if (isRefreshing()) return;
|
||||
// new TwidereAsyncTask<Object, Object, long[][]>() {
|
||||
//
|
||||
// @Override
|
||||
// protected long[][] doInBackground(final Object... params) {
|
||||
// final long[][] result = new long[3][];
|
||||
// result[0] = getActivatedAccountIds(getActivity());
|
||||
// result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
// result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onPostExecute(final long[][] result) {
|
||||
// final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
// if (twitter == null) return;
|
||||
// twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
|
||||
// twitter.getSentDirectMessagesAsync(result[0], result[2], null);
|
||||
// }
|
||||
//
|
||||
// }.executeTask();
|
||||
// }
|
||||
|
||||
class CacheUserSearchLoader(
|
||||
fragment: MessagesConversationFragment,
|
||||
accountKey: UserKey,
|
||||
query: String,
|
||||
private val fromCache: Boolean,
|
||||
fromUser: Boolean
|
||||
) : UserSearchLoader(fragment.context, accountKey, query, 0, null, fromUser) {
|
||||
private val userColorNameManager: UserColorNameManager
|
||||
|
||||
init {
|
||||
userColorNameManager = fragment.userColorNameManager
|
||||
}
|
||||
|
||||
override fun loadInBackground(): List<ParcelableUser> {
|
||||
val query = query
|
||||
if (TextUtils.isEmpty(query)) return emptyList()
|
||||
if (fromCache) {
|
||||
val cachedList = ArrayList<ParcelableUser>()
|
||||
val queryEscaped = query.replace("_", "^_")
|
||||
val nicknameKeys = Utils.getMatchedNicknameKeys(query, userColorNameManager)
|
||||
val selection = Expression.or(Expression.likeRaw(Column(CachedUsers.SCREEN_NAME), "?||'%'", "^"),
|
||||
Expression.likeRaw(Column(CachedUsers.NAME), "?||'%'", "^"),
|
||||
Expression.inArgs(Column(CachedUsers.USER_KEY), nicknameKeys.size))
|
||||
val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys)
|
||||
val order = arrayOf(CachedUsers.LAST_SEEN, CachedUsers.SCREEN_NAME, CachedUsers.NAME)
|
||||
val ascending = booleanArrayOf(false, true, true)
|
||||
val orderBy = OrderBy(order, ascending)
|
||||
val c = context.contentResolver.query(CachedUsers.CONTENT_URI,
|
||||
CachedUsers.BASIC_COLUMNS, selection?.sql,
|
||||
selectionArgs, orderBy.sql)!!
|
||||
val i = ParcelableUserCursorIndices(c)
|
||||
c.moveToFirst()
|
||||
while (!c.isAfterLast) {
|
||||
cachedList.add(i.newObject(c))
|
||||
c.moveToNext()
|
||||
}
|
||||
c.close()
|
||||
return cachedList
|
||||
}
|
||||
return super.loadInBackground()
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteConversationConfirmDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
builder.setMessage(R.string.delete_conversation_confirm_message)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val args = arguments
|
||||
val account = args.getParcelable<ParcelableCredentials>(EXTRA_ACCOUNT)
|
||||
val user = args.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
val twitter = twitterWrapper
|
||||
if (account == null || user == null) return
|
||||
twitter.destroyMessageConversationAsync(account.account_key, user.key.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DeleteMessageConfirmDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
builder.setMessage(R.string.delete_message_confirm_message)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val args = arguments
|
||||
val account = args.getParcelable<ParcelableCredentials>(EXTRA_ACCOUNT)
|
||||
val message = args.getParcelable<ParcelableDirectMessage>(EXTRA_MESSAGE)
|
||||
val twitter = twitterWrapper
|
||||
if (account == null || message == null) return
|
||||
twitter.destroyDirectMessageAsync(account.account_key, message.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SetReadStateTask(private val context: Context, private val account: ParcelableCredentials, private val recipient: ParcelableUser) : AsyncTask<Any, Any, Cursor>() {
|
||||
|
||||
@Inject
|
||||
lateinit var readStateManager: ReadStateManager
|
||||
|
||||
init {
|
||||
GeneralComponentHelper.build(context).inject(this)
|
||||
}
|
||||
|
||||
override fun doInBackground(vararg params: Any): Cursor {
|
||||
val resolver = context.contentResolver
|
||||
val projection = arrayOf(ConversationEntries.MESSAGE_ID)
|
||||
val selection = Expression.and(
|
||||
Expression.equalsArgs(ConversationEntries.ACCOUNT_KEY),
|
||||
Expression.equalsArgs(ConversationEntries.CONVERSATION_ID)).sql
|
||||
val selectionArgs = arrayOf(account.account_key.toString(), recipient.key.toString())
|
||||
val orderBy = OrderBy(ConversationEntries.MESSAGE_ID, false).sql
|
||||
return resolver.query(ConversationEntries.CONTENT_URI, projection, selection,
|
||||
selectionArgs, orderBy)
|
||||
}
|
||||
|
||||
override fun onPostExecute(cursor: Cursor) {
|
||||
if (cursor.moveToFirst()) {
|
||||
val messageIdIdx = cursor.getColumnIndex(ConversationEntries.MESSAGE_ID)
|
||||
val key = "${account.account_key}-${recipient.key}"
|
||||
readStateManager.setPosition(CustomTabType.DIRECT_MESSAGES, key, cursor.getLong(messageIdIdx), false)
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
}
|
||||
|
||||
internal class PanelShowHideListener(private val effectHelper: EffectViewHelper) : RecyclerView.OnScrollListener() {
|
||||
private var showElevation: Boolean = false
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
val showElevation = layoutManager.findLastCompletelyVisibleItemPosition() < layoutManager.itemCount - 1
|
||||
if (showElevation != showElevation) {
|
||||
effectHelper.setState(showElevation)
|
||||
}
|
||||
this.showElevation = showElevation
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
effectHelper.resetState(showElevation)
|
||||
}
|
||||
}
|
||||
|
||||
internal class PanelElevationProperty(private val elevation: Float) : Property<View, Float>(java.lang.Float.TYPE, null) {
|
||||
|
||||
override fun set(`object`: View, value: Float?) {
|
||||
ViewCompat.setTranslationZ(`object`, elevation * value!!)
|
||||
}
|
||||
|
||||
override fun get(`object`: View): Float? {
|
||||
return ViewCompat.getTranslationZ(`object`) / elevation
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
// Constants
|
||||
private val LOADER_ID_SEARCH_USERS = 1
|
||||
private val EXTRA_FROM_CACHE = "from_cache"
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class PhishingLinkWarningDialogFragment extends BaseDialogFragment implements OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return;
|
||||
final Uri uri = args.getParcelable(EXTRA_URI);
|
||||
if (uri == null) return;
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(uri);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle(android.R.string.dialog_alert_title);
|
||||
builder.setView(R.layout.dialog_phishing_link_warning);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_URI
|
||||
|
||||
class PhishingLinkWarningDialogFragment : BaseDialogFragment(), OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val args = arguments ?: return
|
||||
val uri = args.getParcelable<Uri>(EXTRA_URI) ?: return
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = uri
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(android.R.string.dialog_alert_title)
|
||||
builder.setView(R.layout.dialog_phishing_link_warning)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class ProgressDialogFragment extends BaseDialogFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
dialog.setMessage(getString(R.string.please_wait));
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static ProgressDialogFragment show(final FragmentActivity activity, final String tag) {
|
||||
if (activity == null) return null;
|
||||
final ProgressDialogFragment f = new ProgressDialogFragment();
|
||||
f.show(activity.getSupportFragmentManager(), tag);
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.app.ProgressDialog
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentActivity
|
||||
|
||||
import org.mariotaku.twidere.R
|
||||
|
||||
class ProgressDialogFragment : BaseDialogFragment() {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = ProgressDialog(activity)
|
||||
dialog.setMessage(getString(R.string.please_wait))
|
||||
return dialog
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun show(activity: FragmentActivity, tag: String): ProgressDialogFragment {
|
||||
val f = ProgressDialogFragment()
|
||||
f.show(activity.supportFragmentManager, tag)
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class ReportSpamDialogFragment extends BaseDialogFragment implements DialogInterface.OnClickListener {
|
||||
|
||||
public static final String FRAGMENT_TAG = "create_user_block";
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableUser user = getUser();
|
||||
final AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
if (user == null || twitter == null) return;
|
||||
twitter.reportSpamAsync(user.account_key, user.key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final Context context = activity;
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
final ParcelableUser user = getUser();
|
||||
if (user != null) {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String displayName = mUserColorNameManager.getDisplayName(user, nameFirst);
|
||||
builder.setTitle(getString(R.string.report_user, displayName));
|
||||
builder.setMessage(getString(R.string.report_user_confirm_message, displayName));
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private ParcelableUser getUser() {
|
||||
final Bundle args = getArguments();
|
||||
if (!args.containsKey(EXTRA_USER)) return null;
|
||||
return args.getParcelable(EXTRA_USER);
|
||||
}
|
||||
|
||||
public static ReportSpamDialogFragment show(final FragmentManager fm, final ParcelableUser user) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER, user);
|
||||
final ReportSpamDialogFragment f = new ReportSpamDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG);
|
||||
return f;
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
|
||||
class ReportSpamDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val user = user ?: return
|
||||
twitterWrapper.reportSpamAsync(user.account_key, user.key)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
val user = user
|
||||
if (user != null) {
|
||||
val nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
||||
val displayName = userColorNameManager.getDisplayName(user, nameFirst)
|
||||
builder.setTitle(getString(R.string.report_user, displayName))
|
||||
builder.setMessage(getString(R.string.report_user_confirm_message, displayName))
|
||||
}
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
private val user: ParcelableUser?
|
||||
get() {
|
||||
val args = arguments
|
||||
if (!args.containsKey(EXTRA_USER)) return null
|
||||
return args.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val FRAGMENT_TAG = "create_user_block"
|
||||
|
||||
fun show(fm: FragmentManager, user: ParcelableUser): ReportSpamDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER, user)
|
||||
val f = ReportSpamDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG)
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
@ -130,7 +130,7 @@ public class RetweetQuoteDialogFragment extends BaseDialogFragment {
|
||||
commentContainer.setVisibility(useQuote ? View.VISIBLE : View.GONE);
|
||||
editComment.setAccountKey(status.account_key);
|
||||
|
||||
final boolean sendByEnter = mPreferences.getBoolean(KEY_QUICK_SEND);
|
||||
final boolean sendByEnter = preferences.getBoolean(KEY_QUICK_SEND);
|
||||
final EditTextEnterHandler enterHandler = EditTextEnterHandler.attach(editComment, new EditTextEnterHandler.EnterListener() {
|
||||
@Override
|
||||
public boolean shouldCallListener() {
|
||||
@ -176,7 +176,7 @@ public class RetweetQuoteDialogFragment extends BaseDialogFragment {
|
||||
commentMenu.setOnTouchListener(mPopupMenu.getDragToOpenListener());
|
||||
mPopupMenu.inflate(R.menu.menu_dialog_comment);
|
||||
final Menu menu = mPopupMenu.getMenu();
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.quote_original_status,
|
||||
MenuUtils.Companion.setMenuItemAvailability(menu, R.id.quote_original_status,
|
||||
status.retweet_id != null || status.quoted_id != null);
|
||||
mPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
@ -196,7 +196,7 @@ public class RetweetQuoteDialogFragment extends BaseDialogFragment {
|
||||
if (editComment.length() > 0) {
|
||||
dismissDialog = retweetOrQuote(credentials, status, SHOW_PROTECTED_CONFIRM);
|
||||
} else if (isMyRetweet(status)) {
|
||||
mTwitterWrapper.cancelRetweetAsync(status.account_key, status.id, status.my_retweet_id);
|
||||
twitterWrapper.cancelRetweetAsync(status.account_key, status.id, status.my_retweet_id);
|
||||
dismissDialog = true;
|
||||
} else if (useQuote(!status.user_is_protected, credentials)) {
|
||||
dismissDialog = retweetOrQuote(credentials, status, SHOW_PROTECTED_CONFIRM);
|
||||
@ -235,7 +235,7 @@ public class RetweetQuoteDialogFragment extends BaseDialogFragment {
|
||||
}
|
||||
final StatusTextCountView textCountView = (StatusTextCountView) alertDialog.findViewById(R.id.comment_text_count);
|
||||
assert textCountView != null;
|
||||
textCountView.setTextCount(mValidator.getTweetLength(s.toString()));
|
||||
textCountView.setTextCount(validator.getTweetLength(s.toString()));
|
||||
}
|
||||
|
||||
private ParcelableStatus getStatus() {
|
||||
@ -247,7 +247,7 @@ public class RetweetQuoteDialogFragment extends BaseDialogFragment {
|
||||
@CheckResult
|
||||
private boolean retweetOrQuote(ParcelableAccount account, ParcelableStatus status,
|
||||
boolean showProtectedConfirmation) {
|
||||
AsyncTwitterWrapper twitter = mTwitterWrapper;
|
||||
AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
final Dialog dialog = getDialog();
|
||||
if (dialog == null || twitter == null) return false;
|
||||
final EditText editComment = (EditText) dialog.findViewById(R.id.edit_comment);
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class SensitiveContentWarningDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final Context context = getActivity();
|
||||
final Bundle args = getArguments();
|
||||
if (args == null || context == null) return;
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
final ParcelableMedia current = args.getParcelable(EXTRA_CURRENT_MEDIA);
|
||||
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
|
||||
final Bundle option = args.getBundle(EXTRA_ACTIVITY_OPTIONS);
|
||||
final boolean newDocument = args.getBoolean(EXTRA_NEW_DOCUMENT);
|
||||
final ParcelableMedia[] media = Utils.newParcelableArray(args.getParcelableArray(EXTRA_MEDIA),
|
||||
ParcelableMedia.CREATOR);
|
||||
IntentUtils.openMediaDirectly(context, accountKey, status, null, current, media,
|
||||
option, newDocument);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(android.R.string.dialog_alert_title);
|
||||
builder.setMessage(R.string.sensitive_content_warning);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.*
|
||||
import org.mariotaku.twidere.model.ParcelableMedia
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
class SensitiveContentWarningDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val context = activity
|
||||
val args = arguments
|
||||
if (args == null || context == null) return
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val current = args.getParcelable<ParcelableMedia>(EXTRA_CURRENT_MEDIA)
|
||||
val status = args.getParcelable<ParcelableStatus>(EXTRA_STATUS)
|
||||
val option = args.getBundle(EXTRA_ACTIVITY_OPTIONS)
|
||||
val newDocument = args.getBoolean(EXTRA_NEW_DOCUMENT)
|
||||
val media = Utils.newParcelableArray(args.getParcelableArray(EXTRA_MEDIA),
|
||||
ParcelableMedia.CREATOR)
|
||||
IntentUtils.openMediaDirectly(context, accountKey, status, null, current, media,
|
||||
option, newDocument)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(android.R.string.dialog_alert_title)
|
||||
builder.setMessage(R.string.sensitive_content_warning)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
|
||||
public class SetUserNicknameDialogFragment extends BaseDialogFragment implements OnClickListener {
|
||||
|
||||
private static final String FRAGMENT_TAG_SET_USER_NICKNAME = "set_user_nickname";
|
||||
private EditText mEditText;
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
final Bundle args = getArguments();
|
||||
assert args != null;
|
||||
final String text = ParseUtils.parseString(mEditText.getText());
|
||||
final UserKey userId = args.getParcelable(EXTRA_USER_KEY);
|
||||
assert userId != null;
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
mUserColorNameManager.clearUserNickname(userId);
|
||||
} else {
|
||||
mUserColorNameManager.setUserNickname(userId, text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogInterface.BUTTON_NEUTRAL: {
|
||||
mUserColorNameManager.clearUserNickname(userId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final Bundle args = getArguments();
|
||||
final String nick = args.getString(EXTRA_NAME);
|
||||
final Context context = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.set_nickname);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
if (!TextUtils.isEmpty(nick)) {
|
||||
builder.setNeutralButton(R.string.clear, this);
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
final FrameLayout view = new FrameLayout(context);
|
||||
mEditText = new AppCompatEditText(context);
|
||||
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
lp.leftMargin = lp.topMargin = lp.bottomMargin = lp.rightMargin = getResources().getDimensionPixelSize(
|
||||
R.dimen.element_spacing_normal);
|
||||
view.addView(mEditText, lp);
|
||||
builder.setView(view);
|
||||
mEditText.setText(nick);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
public static SetUserNicknameDialogFragment show(final FragmentManager fm, final UserKey userKey, final String nickname) {
|
||||
final SetUserNicknameDialogFragment f = new SetUserNicknameDialogFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_USER_KEY, userKey);
|
||||
args.putString(EXTRA_NAME, nickname);
|
||||
f.setArguments(args);
|
||||
f.show(fm, FRAGMENT_TAG_SET_USER_NICKNAME);
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.text.TextUtils
|
||||
import android.widget.EditText
|
||||
import org.mariotaku.ktextension.empty
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_NAME
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER_KEY
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
|
||||
class SetUserNicknameDialogFragment : BaseDialogFragment(), OnClickListener {
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
val args = arguments!!
|
||||
val editName = (dialog as AlertDialog).findViewById(R.id.editName) as EditText
|
||||
val userId = args.getParcelable<UserKey>(EXTRA_USER_KEY)!!
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
if (editName.empty) {
|
||||
userColorNameManager.clearUserNickname(userId)
|
||||
} else {
|
||||
userColorNameManager.setUserNickname(userId, editName.text.toString())
|
||||
}
|
||||
}
|
||||
DialogInterface.BUTTON_NEUTRAL -> {
|
||||
userColorNameManager.clearUserNickname(userId)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val args = arguments
|
||||
val nick = args.getString(EXTRA_NAME)
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(R.string.set_nickname)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
if (!TextUtils.isEmpty(nick)) {
|
||||
builder.setNeutralButton(R.string.clear, this)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
builder.setView(R.layout.dialog_edit_user_nickname)
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val FRAGMENT_TAG_SET_USER_NICKNAME = "set_user_nickname"
|
||||
|
||||
fun show(fm: FragmentManager, userKey: UserKey, nickname: String): SetUserNicknameDialogFragment {
|
||||
val f = SetUserNicknameDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_USER_KEY, userKey)
|
||||
args.putString(EXTRA_NAME, nickname)
|
||||
f.arguments = args
|
||||
f.show(fm, FRAGMENT_TAG_SET_USER_NICKNAME)
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,506 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NdefRecord;
|
||||
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
|
||||
import android.nfc.NfcEvent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.rengwuxian.materialedittext.MaterialEditText;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.microblog.library.MicroBlog;
|
||||
import org.mariotaku.microblog.library.MicroBlogException;
|
||||
import org.mariotaku.microblog.library.twitter.model.UserList;
|
||||
import org.mariotaku.microblog.library.twitter.model.UserListUpdate;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.AccountSelectorActivity;
|
||||
import org.mariotaku.twidere.activity.UserListSelectorActivity;
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.message.UserListSubscriptionEvent;
|
||||
import org.mariotaku.twidere.model.message.UserListUpdatedEvent;
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserListUtils;
|
||||
import org.mariotaku.twidere.text.validator.UserListNameValidator;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.LinkCreator;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class UserListFragment extends AbsToolbarTabPagesFragment implements OnClickListener,
|
||||
LoaderCallbacks<SingleResponse<ParcelableUserList>>, SystemWindowsInsetsCallback,
|
||||
SupportFragmentCallback {
|
||||
|
||||
private boolean mUserListLoaderInitialized;
|
||||
|
||||
private ParcelableUserList mUserList;
|
||||
|
||||
public void displayUserList(final ParcelableUserList userList) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
getLoaderManager().destroyLoader(0);
|
||||
mUserList = userList;
|
||||
|
||||
if (userList != null) {
|
||||
activity.setTitle(userList.name);
|
||||
} else {
|
||||
activity.setTitle(R.string.user_list);
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
public void getUserListInfo(final boolean omitIntentExtra) {
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(0);
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, omitIntentExtra);
|
||||
if (!mUserListLoaderInitialized) {
|
||||
lm.initLoader(0, args, this);
|
||||
mUserListLoaderInitialized = true;
|
||||
} else {
|
||||
lm.restartLoader(0, args, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
switch (requestCode) {
|
||||
case REQUEST_SELECT_USER: {
|
||||
final ParcelableUserList userList = mUserList;
|
||||
if (resultCode != Activity.RESULT_OK || !data.hasExtra(EXTRA_USER) || twitter == null
|
||||
|| userList == null) return;
|
||||
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
|
||||
twitter.addUserListMembersAsync(userList.account_key, userList.id, user);
|
||||
return;
|
||||
}
|
||||
case REQUEST_SELECT_ACCOUNT: {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null || !data.hasExtra(EXTRA_ID)) return;
|
||||
final ParcelableUserList userList = mUserList;
|
||||
final UserKey accountKey = data.getParcelableExtra(EXTRA_ACCOUNT_KEY);
|
||||
IntentUtils.openUserListDetails(getActivity(), accountKey, userList.id,
|
||||
userList.user_key, userList.user_screen_name, userList.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final FragmentActivity activity = getActivity();
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
Utils.setNdefPushMessageCallback(activity, new CreateNdefMessageCallback() {
|
||||
|
||||
@Override
|
||||
public NdefMessage createNdefMessage(NfcEvent event) {
|
||||
final ParcelableUserList userList = getUserList();
|
||||
if (userList == null) return null;
|
||||
return new NdefMessage(new NdefRecord[]{
|
||||
NdefRecord.createUri(LinkCreator.getTwitterUserListLink(userList.user_screen_name, userList.name)),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
getUserListInfo(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTabs(SupportTabsAdapter adapter) {
|
||||
final Bundle args = getArguments(), tabArgs = new Bundle();
|
||||
if (args.containsKey(EXTRA_USER_LIST)) {
|
||||
final ParcelableUserList userList = args.getParcelable(EXTRA_USER_LIST);
|
||||
assert userList != null;
|
||||
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userList.account_key);
|
||||
tabArgs.putParcelable(EXTRA_USER_KEY, userList.user_key);
|
||||
tabArgs.putString(EXTRA_SCREEN_NAME, userList.user_screen_name);
|
||||
tabArgs.putString(EXTRA_LIST_ID, userList.id);
|
||||
tabArgs.putString(EXTRA_LIST_NAME, userList.name);
|
||||
} else {
|
||||
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, args.getParcelable(EXTRA_ACCOUNT_KEY));
|
||||
tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable(EXTRA_USER_KEY));
|
||||
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
|
||||
tabArgs.putString(EXTRA_LIST_ID, args.getString(EXTRA_LIST_ID));
|
||||
tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME));
|
||||
}
|
||||
adapter.addTab(UserListTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0, null);
|
||||
adapter.addTab(UserListMembersFragment.class, tabArgs, getString(R.string.members), null, 1, null);
|
||||
adapter.addTab(UserListSubscribersFragment.class, tabArgs, getString(R.string.subscribers), null, 2, null);
|
||||
}
|
||||
|
||||
public ParcelableUserList getUserList() {
|
||||
return mUserList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
bus.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
bus.unregister(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mUserList = null;
|
||||
getLoaderManager().destroyLoader(0);
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_user_list, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
final ParcelableUserList userList = mUserList;
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.info, userList != null);
|
||||
menu.removeGroup(MENU_GROUP_USER_LIST_EXTENSION);
|
||||
if (userList != null) {
|
||||
final boolean isMyList = userList.user_key.equals(userList.account_key);
|
||||
final boolean isFollowing = userList.is_following;
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.edit, isMyList);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.follow, !isMyList);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.add, isMyList);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.delete, isMyList);
|
||||
final MenuItem followItem = menu.findItem(R.id.follow);
|
||||
if (isFollowing) {
|
||||
followItem.setIcon(R.drawable.ic_action_cancel);
|
||||
followItem.setTitle(R.string.unsubscribe);
|
||||
} else {
|
||||
followItem.setIcon(R.drawable.ic_action_add);
|
||||
followItem.setTitle(R.string.subscribe);
|
||||
}
|
||||
final Intent extensionsIntent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST);
|
||||
extensionsIntent.setExtrasClassLoader(getActivity().getClassLoader());
|
||||
extensionsIntent.putExtra(EXTRA_USER_LIST, userList);
|
||||
MenuUtils.addIntentToMenu(getActivity(), menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION);
|
||||
} else {
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.edit, false);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.follow, false);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.add, false);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.delete, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
final ParcelableUserList userList = mUserList;
|
||||
if (twitter == null || userList == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.add: {
|
||||
if (!userList.user_key.equals(userList.account_key)) return false;
|
||||
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
|
||||
intent.setClass(getActivity(), UserListSelectorActivity.class);
|
||||
intent.putExtra(EXTRA_ACCOUNT_KEY, userList.account_key);
|
||||
startActivityForResult(intent, REQUEST_SELECT_USER);
|
||||
break;
|
||||
}
|
||||
case R.id.delete: {
|
||||
if (!userList.user_key.equals(userList.account_key)) return false;
|
||||
DestroyUserListDialogFragment.show(getFragmentManager(), userList);
|
||||
break;
|
||||
}
|
||||
case R.id.edit: {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_ACCOUNT_KEY, userList.account_key);
|
||||
args.putString(EXTRA_LIST_NAME, userList.name);
|
||||
args.putString(EXTRA_DESCRIPTION, userList.description);
|
||||
args.putBoolean(EXTRA_IS_PUBLIC, userList.is_public);
|
||||
args.putString(EXTRA_LIST_ID, userList.id);
|
||||
final DialogFragment f = new EditUserListDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(getFragmentManager(), "edit_user_list_details");
|
||||
return true;
|
||||
}
|
||||
case R.id.follow: {
|
||||
if (userList.is_following) {
|
||||
DestroyUserListSubscriptionDialogFragment.show(getFragmentManager(), userList);
|
||||
} else {
|
||||
twitter.createUserListSubscriptionAsync(userList.account_key, userList.id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case R.id.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;
|
||||
}
|
||||
default: {
|
||||
if (item.getIntent() != null) {
|
||||
try {
|
||||
startActivity(item.getIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.errorContainer: {
|
||||
getUserListInfo(true);
|
||||
break;
|
||||
}
|
||||
case R.id.profile_image: {
|
||||
final ParcelableUserList userList = mUserList;
|
||||
if (userList == null) return;
|
||||
IntentUtils.openUserProfile(getActivity(), userList.account_key,
|
||||
userList.user_key, userList.user_screen_name, null,
|
||||
preferences.getBoolean(KEY_NEW_DOCUMENT_API), null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<SingleResponse<ParcelableUserList>> onCreateLoader(final int id, final Bundle args) {
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
final UserKey userKey = args.getParcelable(EXTRA_USER_KEY);
|
||||
final String listId = args.getString(EXTRA_LIST_ID);
|
||||
final String listName = args.getString(EXTRA_LIST_NAME);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
final boolean omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true);
|
||||
return new ParcelableUserListLoader(getActivity(), omitIntentExtra, getArguments(), accountKey, listId,
|
||||
listName, userKey, screenName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<SingleResponse<ParcelableUserList>> loader,
|
||||
final SingleResponse<ParcelableUserList> data) {
|
||||
if (data == null) return;
|
||||
if (getActivity() == null) return;
|
||||
if (data.hasData()) {
|
||||
final ParcelableUserList list = data.getData();
|
||||
displayUserList(list);
|
||||
} else if (data.hasException()) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<ParcelableUserList>> loader) {
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onUserListUpdated(UserListUpdatedEvent event) {
|
||||
if (mUserList == null) return;
|
||||
if (TextUtils.equals(event.getUserList().id, mUserList.id)) {
|
||||
getUserListInfo(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onUserListSubscriptionChanged(UserListSubscriptionEvent event) {
|
||||
if (mUserList == null) return;
|
||||
if (TextUtils.equals(event.getUserList().id, mUserList.id)) {
|
||||
getUserListInfo(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditUserListDialogFragment extends BaseDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private String mName, mDescription;
|
||||
private UserKey mAccountKey;
|
||||
private String mListId;
|
||||
private boolean mIsPublic;
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE: {
|
||||
final AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
final MaterialEditText editName = (MaterialEditText) alertDialog.findViewById(R.id.name);
|
||||
final MaterialEditText editDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
|
||||
final CheckBox editIsPublic = (CheckBox) alertDialog.findViewById(R.id.is_public);
|
||||
assert editName != null && editDescription != null && editIsPublic != null;
|
||||
final String name = ParseUtils.parseString(editName.getText());
|
||||
final String description = ParseUtils.parseString(editDescription.getText());
|
||||
final boolean isPublic = editIsPublic.isChecked();
|
||||
if (TextUtils.isEmpty(name)) return;
|
||||
final UserListUpdate update = new UserListUpdate();
|
||||
update.setMode(isPublic ? UserList.Mode.PUBLIC : UserList.Mode.PRIVATE);
|
||||
update.setName(name);
|
||||
update.setDescription(description);
|
||||
mTwitterWrapper.updateUserListDetails(mAccountKey, mListId, update);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
final Bundle bundle = savedInstanceState == null ? getArguments() : savedInstanceState;
|
||||
mAccountKey = bundle != null ? bundle.<UserKey>getParcelable(EXTRA_ACCOUNT_KEY) : null;
|
||||
mListId = bundle != null ? bundle.getString(EXTRA_LIST_ID) : null;
|
||||
mName = bundle != null ? bundle.getString(EXTRA_LIST_NAME) : null;
|
||||
mDescription = bundle != null ? bundle.getString(EXTRA_DESCRIPTION) : null;
|
||||
mIsPublic = bundle == null || bundle.getBoolean(EXTRA_IS_PUBLIC, true);
|
||||
final Context context = getActivity();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setView(R.layout.dialog_user_list_detail_editor);
|
||||
builder.setTitle(R.string.user_list);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, this);
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
|
||||
AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
MaterialEditText editName = (MaterialEditText) alertDialog.findViewById(R.id.name);
|
||||
MaterialEditText editDescription = (MaterialEditText) alertDialog.findViewById(R.id.description);
|
||||
CheckBox editPublic = (CheckBox) alertDialog.findViewById(R.id.is_public);
|
||||
assert editName != null && editDescription != null && editPublic != null;
|
||||
editName.addValidator(new UserListNameValidator(getString(R.string.invalid_list_name)));
|
||||
if (mName != null) {
|
||||
editName.setText(mName);
|
||||
}
|
||||
if (mDescription != null) {
|
||||
editDescription.setText(mDescription);
|
||||
}
|
||||
editPublic.setChecked(mIsPublic);
|
||||
}
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(final Bundle outState) {
|
||||
outState.putParcelable(EXTRA_ACCOUNT_KEY, mAccountKey);
|
||||
outState.putString(EXTRA_LIST_ID, mListId);
|
||||
outState.putString(EXTRA_LIST_NAME, mName);
|
||||
outState.putString(EXTRA_DESCRIPTION, mDescription);
|
||||
outState.putBoolean(EXTRA_IS_PUBLIC, mIsPublic);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ParcelableUserListLoader extends AsyncTaskLoader<SingleResponse<ParcelableUserList>> {
|
||||
|
||||
private final boolean mOmitIntentExtra;
|
||||
private final Bundle mExtras;
|
||||
private final UserKey mAccountKey;
|
||||
private final UserKey mUserKey;
|
||||
private final String mListId;
|
||||
private final String mScreenName, mListName;
|
||||
|
||||
private ParcelableUserListLoader(final Context context, final boolean omitIntentExtra,
|
||||
final Bundle extras, final UserKey accountKey,
|
||||
final String listId, final String listName,
|
||||
final UserKey userKey, final String screenName) {
|
||||
super(context);
|
||||
mOmitIntentExtra = omitIntentExtra;
|
||||
mExtras = extras;
|
||||
mAccountKey = accountKey;
|
||||
mUserKey = userKey;
|
||||
mListId = listId;
|
||||
mScreenName = screenName;
|
||||
mListName = listName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<ParcelableUserList> loadInBackground() {
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableUserList cache = mExtras.getParcelable(EXTRA_USER_LIST);
|
||||
if (cache != null) return SingleResponse.getInstance(cache);
|
||||
}
|
||||
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(getContext(), mAccountKey,
|
||||
true);
|
||||
if (twitter == null) return SingleResponse.getInstance();
|
||||
try {
|
||||
final UserList list;
|
||||
if (mListId != null) {
|
||||
list = twitter.showUserList(mListId);
|
||||
} else if (mUserKey != null) {
|
||||
list = twitter.showUserList(mListName, mUserKey.getId());
|
||||
} else if (mScreenName != null) {
|
||||
list = twitter.showUserListByScrenName(mListName, mScreenName);
|
||||
} else
|
||||
return SingleResponse.getInstance();
|
||||
return SingleResponse.getInstance(ParcelableUserListUtils.from(list, mAccountKey));
|
||||
} catch (final MicroBlogException e) {
|
||||
return SingleResponse.getInstance(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.nfc.NdefMessage
|
||||
import android.nfc.NdefRecord
|
||||
import android.nfc.NfcAdapter.CreateNdefMessageCallback
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.AsyncTaskLoader
|
||||
import android.support.v4.content.Loader
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
import android.widget.CheckBox
|
||||
import com.rengwuxian.materialedittext.MaterialEditText
|
||||
import com.squareup.otto.Subscribe
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.twitter.model.UserList
|
||||
import org.mariotaku.microblog.library.twitter.model.UserListUpdate
|
||||
import org.mariotaku.twidere.Constants.*
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.activity.AccountSelectorActivity
|
||||
import org.mariotaku.twidere.activity.UserListSelectorActivity
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
import org.mariotaku.twidere.model.ParcelableUserList
|
||||
import org.mariotaku.twidere.model.SingleResponse
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.message.UserListSubscriptionEvent
|
||||
import org.mariotaku.twidere.model.message.UserListUpdatedEvent
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserListUtils
|
||||
import org.mariotaku.twidere.text.validator.UserListNameValidator
|
||||
import org.mariotaku.twidere.util.*
|
||||
|
||||
class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener, LoaderCallbacks<SingleResponse<ParcelableUserList>>, SystemWindowsInsetsCallback, SupportFragmentCallback {
|
||||
|
||||
private var mUserListLoaderInitialized: Boolean = false
|
||||
|
||||
var userList: ParcelableUserList? = null
|
||||
private set
|
||||
|
||||
fun displayUserList(userList: ParcelableUserList?) {
|
||||
val activity = activity ?: return
|
||||
loaderManager.destroyLoader(0)
|
||||
this.userList = userList
|
||||
|
||||
if (userList != null) {
|
||||
activity.title = userList.name
|
||||
} else {
|
||||
activity.setTitle(R.string.user_list)
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
fun getUserListInfo(omitIntentExtra: Boolean) {
|
||||
val lm = loaderManager
|
||||
lm.destroyLoader(0)
|
||||
val args = Bundle(arguments)
|
||||
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, omitIntentExtra)
|
||||
if (!mUserListLoaderInitialized) {
|
||||
lm.initLoader(0, args, this)
|
||||
mUserListLoaderInitialized = true
|
||||
} else {
|
||||
lm.restartLoader(0, args, this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
val twitter = twitterWrapper
|
||||
when (requestCode) {
|
||||
REQUEST_SELECT_USER -> {
|
||||
val userList = this.userList
|
||||
if (resultCode != Activity.RESULT_OK || !data!!.hasExtra(EXTRA_USER) || twitter == null
|
||||
|| userList == null)
|
||||
return
|
||||
val user = data.getParcelableExtra<ParcelableUser>(EXTRA_USER)
|
||||
twitter.addUserListMembersAsync(userList.account_key, userList.id, user)
|
||||
return
|
||||
}
|
||||
REQUEST_SELECT_ACCOUNT -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null || !data.hasExtra(EXTRA_ID)) return
|
||||
val userList = this.userList
|
||||
val accountKey = data.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
IntentUtils.openUserListDetails(activity, accountKey, userList!!.id,
|
||||
userList.user_key, userList.user_screen_name, userList.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
val activity = activity
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
Utils.setNdefPushMessageCallback(activity, CreateNdefMessageCallback {
|
||||
val userList = userList ?: return@CreateNdefMessageCallback null
|
||||
NdefMessage(arrayOf(NdefRecord.createUri(LinkCreator.getTwitterUserListLink(userList.user_screen_name, userList.name))))
|
||||
})
|
||||
|
||||
getUserListInfo(false)
|
||||
}
|
||||
|
||||
override fun addTabs(adapter: SupportTabsAdapter) {
|
||||
val args = arguments
|
||||
val tabArgs = Bundle()
|
||||
if (args.containsKey(EXTRA_USER_LIST)) {
|
||||
val userList = args.getParcelable<ParcelableUserList>(EXTRA_USER_LIST)!!
|
||||
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userList.account_key)
|
||||
tabArgs.putParcelable(EXTRA_USER_KEY, userList.user_key)
|
||||
tabArgs.putString(EXTRA_SCREEN_NAME, userList.user_screen_name)
|
||||
tabArgs.putString(EXTRA_LIST_ID, userList.id)
|
||||
tabArgs.putString(EXTRA_LIST_NAME, userList.name)
|
||||
} else {
|
||||
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, args.getParcelable(EXTRA_ACCOUNT_KEY))
|
||||
tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable(EXTRA_USER_KEY))
|
||||
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME))
|
||||
tabArgs.putString(EXTRA_LIST_ID, args.getString(EXTRA_LIST_ID))
|
||||
tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME))
|
||||
}
|
||||
adapter.addTab(UserListTimelineFragment::class.java, tabArgs, getString(R.string.statuses), null, 0, null)
|
||||
adapter.addTab(UserListMembersFragment::class.java, tabArgs, getString(R.string.members), null, 1, null)
|
||||
adapter.addTab(UserListSubscribersFragment::class.java, tabArgs, getString(R.string.subscribers), null, 2, null)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
bus.register(this)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
bus.unregister(this)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
userList = null
|
||||
loaderManager.destroyLoader(0)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater!!.inflate(R.menu.menu_user_list, menu)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?) {
|
||||
val userList = this.userList
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.info, userList != null)
|
||||
menu!!.removeGroup(MENU_GROUP_USER_LIST_EXTENSION)
|
||||
if (userList != null) {
|
||||
val isMyList = userList.user_key == userList.account_key
|
||||
val isFollowing = userList.is_following
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.edit, isMyList)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.follow, !isMyList)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.add, isMyList)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.delete, isMyList)
|
||||
val followItem = menu.findItem(R.id.follow)
|
||||
if (isFollowing) {
|
||||
followItem.setIcon(R.drawable.ic_action_cancel)
|
||||
followItem.setTitle(R.string.unsubscribe)
|
||||
} else {
|
||||
followItem.setIcon(R.drawable.ic_action_add)
|
||||
followItem.setTitle(R.string.subscribe)
|
||||
}
|
||||
val extensionsIntent = Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST)
|
||||
extensionsIntent.setExtrasClassLoader(activity.classLoader)
|
||||
extensionsIntent.putExtra(EXTRA_USER_LIST, userList)
|
||||
MenuUtils.addIntentToMenu(activity, menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION)
|
||||
} else {
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.edit, false)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.follow, false)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.add, false)
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.delete, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
val twitter = twitterWrapper
|
||||
val userList = userList ?: return false
|
||||
when (item!!.itemId) {
|
||||
R.id.add -> {
|
||||
if (userList.user_key != userList.account_key) return false
|
||||
val intent = Intent(INTENT_ACTION_SELECT_USER)
|
||||
intent.setClass(activity, UserListSelectorActivity::class.java)
|
||||
intent.putExtra(EXTRA_ACCOUNT_KEY, userList.account_key)
|
||||
startActivityForResult(intent, REQUEST_SELECT_USER)
|
||||
}
|
||||
R.id.delete -> {
|
||||
if (userList.user_key != userList.account_key) return false
|
||||
DestroyUserListDialogFragment.show(fragmentManager, userList)
|
||||
}
|
||||
R.id.edit -> {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EXTRA_ACCOUNT_KEY, userList.account_key)
|
||||
args.putString(EXTRA_LIST_NAME, userList.name)
|
||||
args.putString(EXTRA_DESCRIPTION, userList.description)
|
||||
args.putBoolean(EXTRA_IS_PUBLIC, userList.is_public)
|
||||
args.putString(EXTRA_LIST_ID, userList.id)
|
||||
val f = EditUserListDialogFragment()
|
||||
f.arguments = args
|
||||
f.show(fragmentManager, "edit_user_list_details")
|
||||
return true
|
||||
}
|
||||
R.id.follow -> {
|
||||
if (userList.is_following) {
|
||||
DestroyUserListSubscriptionDialogFragment.show(fragmentManager, userList)
|
||||
} else {
|
||||
twitter.createUserListSubscriptionAsync(userList.account_key, userList.id)
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.open_with_account -> {
|
||||
val intent = Intent(INTENT_ACTION_SELECT_ACCOUNT)
|
||||
intent.setClass(activity, AccountSelectorActivity::class.java)
|
||||
intent.putExtra(EXTRA_SINGLE_SELECTION, true)
|
||||
startActivityForResult(intent, REQUEST_SELECT_ACCOUNT)
|
||||
}
|
||||
else -> {
|
||||
if (item.intent != null) {
|
||||
try {
|
||||
startActivity(item.intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Log.w(LOGTAG, e)
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.errorContainer -> {
|
||||
getUserListInfo(true)
|
||||
}
|
||||
R.id.profile_image -> {
|
||||
val userList = this.userList ?: return
|
||||
IntentUtils.openUserProfile(activity, userList.account_key,
|
||||
userList.user_key, userList.user_screen_name, null,
|
||||
preferences.getBoolean(KEY_NEW_DOCUMENT_API), null)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<SingleResponse<ParcelableUserList>> {
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
|
||||
val listId = args.getString(EXTRA_LIST_ID)
|
||||
val listName = args.getString(EXTRA_LIST_NAME)
|
||||
val screenName = args.getString(EXTRA_SCREEN_NAME)
|
||||
val omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true)
|
||||
return ParcelableUserListLoader(activity, omitIntentExtra, arguments, accountKey, listId,
|
||||
listName, userKey, screenName)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableUserList>>,
|
||||
data: SingleResponse<ParcelableUserList>?) {
|
||||
if (data == null) return
|
||||
if (activity == null) return
|
||||
if (data.hasData()) {
|
||||
val list = data.data
|
||||
displayUserList(list)
|
||||
} else if (data.hasException()) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableUserList>>) {
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onUserListUpdated(event: UserListUpdatedEvent) {
|
||||
if (userList == null) return
|
||||
if (TextUtils.equals(event.userList.id, userList!!.id)) {
|
||||
getUserListInfo(true)
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onUserListSubscriptionChanged(event: UserListSubscriptionEvent) {
|
||||
if (userList == null) return
|
||||
if (TextUtils.equals(event.userList.id, userList!!.id)) {
|
||||
getUserListInfo(true)
|
||||
}
|
||||
}
|
||||
|
||||
class EditUserListDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
|
||||
|
||||
private var mName: String? = null
|
||||
private var mDescription: String? = null
|
||||
private var mAccountKey: UserKey? = null
|
||||
private var mListId: String? = null
|
||||
private var mIsPublic: Boolean = false
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> {
|
||||
val alertDialog = dialog as AlertDialog
|
||||
val editName = alertDialog.findViewById(R.id.name) as MaterialEditText?
|
||||
val editDescription = alertDialog.findViewById(R.id.description) as MaterialEditText?
|
||||
val editIsPublic = alertDialog.findViewById(R.id.is_public) as CheckBox?
|
||||
assert(editName != null && editDescription != null && editIsPublic != null)
|
||||
val name = ParseUtils.parseString(editName!!.text)
|
||||
val description = ParseUtils.parseString(editDescription!!.text)
|
||||
val isPublic = editIsPublic!!.isChecked
|
||||
if (TextUtils.isEmpty(name)) return
|
||||
val update = UserListUpdate()
|
||||
update.setMode(if (isPublic) UserList.Mode.PUBLIC else UserList.Mode.PRIVATE)
|
||||
update.setName(name)
|
||||
update.setDescription(description)
|
||||
twitterWrapper.updateUserListDetails(mAccountKey, mListId, update)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val bundle = savedInstanceState ?: arguments
|
||||
mAccountKey = bundle?.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
mListId = bundle?.getString(EXTRA_LIST_ID)
|
||||
mName = bundle?.getString(EXTRA_LIST_NAME)
|
||||
mDescription = bundle?.getString(EXTRA_DESCRIPTION)
|
||||
mIsPublic = bundle == null || bundle.getBoolean(EXTRA_IS_PUBLIC, true)
|
||||
val context = activity
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setView(R.layout.dialog_user_list_detail_editor)
|
||||
builder.setTitle(R.string.user_list)
|
||||
builder.setPositiveButton(android.R.string.ok, this)
|
||||
builder.setNegativeButton(android.R.string.cancel, this)
|
||||
val dialog = builder.create()
|
||||
dialog.setOnShowListener { dialog ->
|
||||
val alertDialog = dialog as AlertDialog
|
||||
val editName = alertDialog.findViewById(R.id.name) as MaterialEditText?
|
||||
val editDescription = alertDialog.findViewById(R.id.description) as MaterialEditText?
|
||||
val editPublic = alertDialog.findViewById(R.id.is_public) as CheckBox?
|
||||
assert(editName != null && editDescription != null && editPublic != null)
|
||||
editName!!.addValidator(UserListNameValidator(getString(R.string.invalid_list_name)))
|
||||
if (mName != null) {
|
||||
editName.setText(mName)
|
||||
}
|
||||
if (mDescription != null) {
|
||||
editDescription!!.setText(mDescription)
|
||||
}
|
||||
editPublic!!.isChecked = mIsPublic
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
outState!!.putParcelable(EXTRA_ACCOUNT_KEY, mAccountKey)
|
||||
outState.putString(EXTRA_LIST_ID, mListId)
|
||||
outState.putString(EXTRA_LIST_NAME, mName)
|
||||
outState.putString(EXTRA_DESCRIPTION, mDescription)
|
||||
outState.putBoolean(EXTRA_IS_PUBLIC, mIsPublic)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class ParcelableUserListLoader(
|
||||
context: Context,
|
||||
private val omitIntentExtra: Boolean,
|
||||
private val extras: Bundle?,
|
||||
private val accountKey: UserKey,
|
||||
private val listId: String?,
|
||||
private val listName: String,
|
||||
private val userKey: UserKey?,
|
||||
private val screenName: String?
|
||||
) : AsyncTaskLoader<SingleResponse<ParcelableUserList>>(context) {
|
||||
|
||||
override fun loadInBackground(): SingleResponse<ParcelableUserList> {
|
||||
if (!omitIntentExtra && extras != null) {
|
||||
val cache = extras.getParcelable<ParcelableUserList>(EXTRA_USER_LIST)
|
||||
if (cache != null) return SingleResponse.getInstance(cache)
|
||||
}
|
||||
val twitter = MicroBlogAPIFactory.getInstance(context, accountKey,
|
||||
true) ?: return SingleResponse.getInstance<ParcelableUserList>()
|
||||
try {
|
||||
val list: UserList
|
||||
if (listId != null) {
|
||||
list = twitter.showUserList(listId)
|
||||
} else if (userKey != null) {
|
||||
list = twitter.showUserList(listName, userKey.id)
|
||||
} else if (screenName != null) {
|
||||
list = twitter.showUserListByScrenName(listName, screenName)
|
||||
} else
|
||||
return SingleResponse.getInstance<ParcelableUserList>()
|
||||
return SingleResponse.getInstance(ParcelableUserListUtils.from(list, accountKey))
|
||||
} catch (e: MicroBlogException) {
|
||||
return SingleResponse.getInstance<ParcelableUserList>(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override fun onStartLoading() {
|
||||
forceLoad()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,666 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.rengwuxian.materialedittext.MaterialEditText;
|
||||
import com.twitter.Validator;
|
||||
|
||||
import org.mariotaku.abstask.library.AbstractTask;
|
||||
import org.mariotaku.abstask.library.TaskStarter;
|
||||
import org.mariotaku.microblog.library.MicroBlog;
|
||||
import org.mariotaku.microblog.library.MicroBlogException;
|
||||
import org.mariotaku.microblog.library.twitter.model.ProfileUpdate;
|
||||
import org.mariotaku.microblog.library.twitter.model.User;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.ColorPickerDialogActivity;
|
||||
import org.mariotaku.twidere.activity.ThemedImagePickerActivity;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
|
||||
import org.mariotaku.twidere.loader.ParcelableUserLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
|
||||
import org.mariotaku.twidere.task.UpdateAccountInfoTask;
|
||||
import org.mariotaku.twidere.task.UpdateProfileBackgroundImageTask;
|
||||
import org.mariotaku.twidere.task.UpdateProfileBannerImageTask;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileImageTask;
|
||||
import org.mariotaku.twidere.util.HtmlEscapeHelper;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.TwitterValidatorMETLengthChecker;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.ForegroundColorView;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
|
||||
public class UserProfileEditorFragment extends BaseSupportFragment implements OnSizeChangedListener, TextWatcher,
|
||||
OnClickListener, LoaderCallbacks<SingleResponse<ParcelableUser>>,
|
||||
KeyboardShortcutsHandler.TakeAllKeyboardShortcut {
|
||||
|
||||
private static final int LOADER_ID_USER = 1;
|
||||
|
||||
private static final int REQUEST_UPLOAD_PROFILE_IMAGE = 1;
|
||||
private static final int REQUEST_UPLOAD_PROFILE_BANNER_IMAGE = 2;
|
||||
private static final int REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE = 3;
|
||||
private static final int REQUEST_PICK_LINK_COLOR = 11;
|
||||
private static final int REQUEST_PICK_BACKGROUND_COLOR = 12;
|
||||
|
||||
private static final int RESULT_REMOVE_BANNER = 101;
|
||||
private static final String UPDATE_PROFILE_DIALOG_FRAGMENT_TAG = "update_profile";
|
||||
|
||||
private AbstractTask<?, ?, UserProfileEditorFragment> mTask;
|
||||
private ImageView mProfileImageView;
|
||||
private ImageView mProfileBannerView;
|
||||
private ImageView mProfileBackgroundView;
|
||||
private MaterialEditText mEditName;
|
||||
private MaterialEditText mEditDescription;
|
||||
private MaterialEditText mEditLocation;
|
||||
private MaterialEditText mEditUrl;
|
||||
private View mProgressContainer, mEditProfileContent;
|
||||
private View mEditProfileImage;
|
||||
private View mEditProfileBanner;
|
||||
private View mEditProfileBackground;
|
||||
private View mSetLinkColor, mSetBackgroundColor;
|
||||
private ForegroundColorView mLinkColor, mBackgroundColor;
|
||||
private UserKey mAccountId;
|
||||
private ParcelableUser mUser;
|
||||
private boolean mUserInfoLoaderInitialized;
|
||||
private boolean mGetUserInfoCalled;
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(final CharSequence s, final int length, final int start, final int end) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(final CharSequence s, final int length, final int start, final int end) {
|
||||
updateDoneButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
final ParcelableUser user = mUser;
|
||||
if (user == null || (mTask != null && !mTask.isFinished()))
|
||||
return;
|
||||
switch (view.getId()) {
|
||||
case R.id.profile_image: {
|
||||
break;
|
||||
}
|
||||
case R.id.profileBanner: {
|
||||
break;
|
||||
}
|
||||
case R.id.edit_profile_image: {
|
||||
final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(1, 1)
|
||||
.maximumSize(512, 512).build();
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_IMAGE);
|
||||
break;
|
||||
}
|
||||
case R.id.edit_profile_banner: {
|
||||
final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).aspectRatio(3, 1)
|
||||
.maximumSize(1500, 500).addEntry(getString(R.string.remove), "remove_banner", RESULT_REMOVE_BANNER).build();
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BANNER_IMAGE);
|
||||
break;
|
||||
}
|
||||
case R.id.edit_profile_background: {
|
||||
final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).build();
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE);
|
||||
break;
|
||||
}
|
||||
case R.id.set_link_color: {
|
||||
final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class);
|
||||
intent.putExtra(EXTRA_COLOR, user.link_color);
|
||||
intent.putExtra(EXTRA_ALPHA_SLIDER, false);
|
||||
startActivityForResult(intent, REQUEST_PICK_LINK_COLOR);
|
||||
break;
|
||||
}
|
||||
case R.id.set_background_color: {
|
||||
final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class);
|
||||
intent.putExtra(EXTRA_COLOR, user.background_color);
|
||||
intent.putExtra(EXTRA_ALPHA_SLIDER, false);
|
||||
startActivityForResult(intent, REQUEST_PICK_BACKGROUND_COLOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<SingleResponse<ParcelableUser>> onCreateLoader(final int id, final Bundle args) {
|
||||
mProgressContainer.setVisibility(View.VISIBLE);
|
||||
mEditProfileContent.setVisibility(View.GONE);
|
||||
return new ParcelableUserLoader(getActivity(), mAccountId, mAccountId, null, getArguments(),
|
||||
false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<SingleResponse<ParcelableUser>> loader,
|
||||
final SingleResponse<ParcelableUser> data) {
|
||||
if (data.getData() != null && data.getData().key != null) {
|
||||
displayUser(data.getData());
|
||||
} else if (mUser == null) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<ParcelableUser>> loader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_profile_editor, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.save: {
|
||||
final String name = ParseUtils.parseString(mEditName.getText());
|
||||
final String url = ParseUtils.parseString(mEditUrl.getText());
|
||||
final String location = ParseUtils.parseString(mEditLocation.getText());
|
||||
final String description = ParseUtils.parseString(mEditDescription.getText());
|
||||
final int linkColor = mLinkColor.getColor();
|
||||
final int backgroundColor = mBackgroundColor.getColor();
|
||||
mTask = new UpdateProfileTaskInternal(this, mAccountId, mUser, name, url, location,
|
||||
description, linkColor, backgroundColor);
|
||||
TaskStarter.execute(mTask);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
final Bundle args = getArguments();
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
mAccountId = accountKey;
|
||||
if (!Utils.isMyAccount(getActivity(), accountKey)) {
|
||||
getActivity().finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final TwitterValidatorMETLengthChecker lengthChecker = new TwitterValidatorMETLengthChecker(new Validator());
|
||||
mEditName.addTextChangedListener(this);
|
||||
mEditDescription.addTextChangedListener(this);
|
||||
mEditLocation.addTextChangedListener(this);
|
||||
mEditUrl.addTextChangedListener(this);
|
||||
|
||||
mEditDescription.setLengthChecker(lengthChecker);
|
||||
|
||||
mProfileImageView.setOnClickListener(this);
|
||||
mProfileBannerView.setOnClickListener(this);
|
||||
mProfileBackgroundView.setOnClickListener(this);
|
||||
|
||||
mEditProfileImage.setOnClickListener(this);
|
||||
mEditProfileBanner.setOnClickListener(this);
|
||||
mEditProfileBackground.setOnClickListener(this);
|
||||
|
||||
mSetLinkColor.setOnClickListener(this);
|
||||
mSetBackgroundColor.setOnClickListener(this);
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.getParcelable(EXTRA_USER) != null) {
|
||||
final ParcelableUser user = savedInstanceState.getParcelable(EXTRA_USER);
|
||||
assert user != null;
|
||||
displayUser(user);
|
||||
mEditName.setText(savedInstanceState.getString(EXTRA_NAME, user.name));
|
||||
mEditLocation.setText(savedInstanceState.getString(EXTRA_LOCATION, user.location));
|
||||
mEditDescription.setText(savedInstanceState.getString(EXTRA_DESCRIPTION, ParcelableUserUtils.getExpandedDescription(user)));
|
||||
mEditUrl.setText(savedInstanceState.getString(EXTRA_URL, user.url_expanded));
|
||||
} else {
|
||||
getUserInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(final Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelable(EXTRA_USER, mUser);
|
||||
outState.putString(EXTRA_NAME, ParseUtils.parseString(mEditName.getText()));
|
||||
outState.putString(EXTRA_DESCRIPTION, ParseUtils.parseString(mEditDescription.getText()));
|
||||
outState.putString(EXTRA_LOCATION, ParseUtils.parseString(mEditLocation.getText()));
|
||||
outState.putString(EXTRA_URL, ParseUtils.parseString(mEditUrl.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSizeChanged(final View view, final int w, final int h, final int oldw, final int oldh) {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_user_profile_editor, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mProgressContainer = view.findViewById(R.id.progress_container);
|
||||
mEditProfileContent = view.findViewById(R.id.edit_profile_content);
|
||||
mProfileImageView = (ImageView) view.findViewById(R.id.profile_image);
|
||||
mProfileBannerView = (ImageView) view.findViewById(R.id.profileBanner);
|
||||
mProfileBackgroundView = (ImageView) view.findViewById(R.id.profile_background);
|
||||
mEditName = (MaterialEditText) view.findViewById(R.id.name);
|
||||
mEditDescription = (MaterialEditText) view.findViewById(R.id.description);
|
||||
mEditLocation = (MaterialEditText) view.findViewById(R.id.location);
|
||||
mEditUrl = (MaterialEditText) view.findViewById(R.id.url);
|
||||
mEditProfileImage = view.findViewById(R.id.edit_profile_image);
|
||||
mEditProfileBanner = view.findViewById(R.id.edit_profile_banner);
|
||||
mEditProfileBackground = view.findViewById(R.id.edit_profile_background);
|
||||
mLinkColor = (ForegroundColorView) view.findViewById(R.id.link_color);
|
||||
mBackgroundColor = (ForegroundColorView) view.findViewById(R.id.background_color);
|
||||
mSetLinkColor = view.findViewById(R.id.set_link_color);
|
||||
mSetBackgroundColor = view.findViewById(R.id.set_background_color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
if (resultCode == FragmentActivity.RESULT_CANCELED) return;
|
||||
switch (requestCode) {
|
||||
case REQUEST_UPLOAD_PROFILE_BANNER_IMAGE: {
|
||||
if (mTask != null && !mTask.isFinished()) return;
|
||||
if (resultCode == RESULT_REMOVE_BANNER) {
|
||||
mTask = new RemoveProfileBannerTaskInternal(mAccountId);
|
||||
} else {
|
||||
mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAccountId,
|
||||
data.getData(), true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE: {
|
||||
//TODO upload profile background
|
||||
if (mTask != null && !mTask.isFinished()) return;
|
||||
mTask = new UpdateProfileBackgroundImageTaskInternal(getActivity(), mAccountId,
|
||||
data.getData(), false, true);
|
||||
break;
|
||||
}
|
||||
case REQUEST_UPLOAD_PROFILE_IMAGE: {
|
||||
if (mTask != null && !mTask.isFinished()) return;
|
||||
mTask = new UpdateProfileImageTaskInternal(getActivity(), mAccountId,
|
||||
data.getData(), true);
|
||||
break;
|
||||
}
|
||||
case REQUEST_PICK_LINK_COLOR: {
|
||||
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
|
||||
mLinkColor.setColor(data.getIntExtra(EXTRA_COLOR, 0));
|
||||
updateDoneButton();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case REQUEST_PICK_BACKGROUND_COLOR: {
|
||||
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
|
||||
mBackgroundColor.setColor(data.getIntExtra(EXTRA_COLOR, 0));
|
||||
updateDoneButton();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void displayUser(final ParcelableUser user) {
|
||||
if (!mGetUserInfoCalled) return;
|
||||
mGetUserInfoCalled = false;
|
||||
mUser = user;
|
||||
if (user != null) {
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mEditProfileContent.setVisibility(View.VISIBLE);
|
||||
mEditName.setText(user.name);
|
||||
mEditDescription.setText(ParcelableUserUtils.getExpandedDescription(user));
|
||||
mEditLocation.setText(user.location);
|
||||
mEditUrl.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded);
|
||||
mediaLoader.displayProfileImage(mProfileImageView, user);
|
||||
final int defWidth = getResources().getDisplayMetrics().widthPixels;
|
||||
mediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, defWidth);
|
||||
mediaLoader.displayImage(mProfileBackgroundView, user.profile_background_url);
|
||||
mLinkColor.setColor(user.link_color);
|
||||
mBackgroundColor.setColor(user.background_color);
|
||||
if (USER_TYPE_FANFOU_COM.equals(user.key.getHost())) {
|
||||
mEditProfileBanner.setVisibility(View.GONE);
|
||||
} else {
|
||||
mEditProfileBanner.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mEditProfileContent.setVisibility(View.GONE);
|
||||
}
|
||||
updateDoneButton();
|
||||
}
|
||||
|
||||
private void getUserInfo() {
|
||||
if (getActivity() == null || isDetached()) return;
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(LOADER_ID_USER);
|
||||
mGetUserInfoCalled = true;
|
||||
if (mUserInfoLoaderInitialized) {
|
||||
lm.restartLoader(LOADER_ID_USER, null, this);
|
||||
} else {
|
||||
lm.initLoader(LOADER_ID_USER, null, this);
|
||||
mUserInfoLoaderInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mTask != null && !mTask.isFinished()) {
|
||||
TaskStarter.execute(mTask);
|
||||
}
|
||||
}
|
||||
|
||||
private void dismissDialogFragment(final String tag) {
|
||||
executeAfterFragmentResumed(new Action() {
|
||||
@Override
|
||||
public void execute(IBaseFragment fragment) {
|
||||
final FragmentManager fm = getChildFragmentManager();
|
||||
final Fragment f = fm.findFragmentByTag(tag);
|
||||
if (f instanceof DialogFragment) {
|
||||
((DialogFragment) f).dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpdateState(final boolean start) {
|
||||
if (!start) {
|
||||
dismissDialogFragment(UPDATE_PROFILE_DIALOG_FRAGMENT_TAG);
|
||||
return;
|
||||
}
|
||||
executeAfterFragmentResumed(new Action() {
|
||||
@Override
|
||||
public void execute(IBaseFragment fragment) {
|
||||
final FragmentManager fm = getChildFragmentManager();
|
||||
ProgressDialogFragment df = new ProgressDialogFragment();
|
||||
df.show(fm, UPDATE_PROFILE_DIALOG_FRAGMENT_TAG);
|
||||
df.setCancelable(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean stringEquals(final CharSequence str1, final CharSequence str2) {
|
||||
if (str1 == null || str2 == null) return str1 == str2;
|
||||
if (str1.length() != str2.length()) return false;
|
||||
for (int i = 0, j = str1.length(); i < j; i++) {
|
||||
if (str1.charAt(i) != str2.charAt(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateDoneButton() {
|
||||
|
||||
}
|
||||
|
||||
static class UpdateProfileTaskInternal extends AbstractTask<Object, SingleResponse<ParcelableUser>,
|
||||
UserProfileEditorFragment> {
|
||||
|
||||
private static final String DIALOG_FRAGMENT_TAG = "updating_user_profile";
|
||||
private final FragmentActivity mActivity;
|
||||
|
||||
// Data fields
|
||||
private final UserKey mAccountKey;
|
||||
private final ParcelableUser mOriginal;
|
||||
private final String mName;
|
||||
private final String mUrl;
|
||||
private final String mLocation;
|
||||
private final String mDescription;
|
||||
private final int mLinkColor;
|
||||
private final int mBackgroundColor;
|
||||
|
||||
public UpdateProfileTaskInternal(final UserProfileEditorFragment fragment,
|
||||
final UserKey accountKey, final ParcelableUser original,
|
||||
final String name, final String url, final String location,
|
||||
final String description, final int linkColor,
|
||||
final int backgroundColor) {
|
||||
mActivity = fragment.getActivity();
|
||||
mAccountKey = accountKey;
|
||||
mOriginal = original;
|
||||
mName = name;
|
||||
mUrl = url;
|
||||
mLocation = location;
|
||||
mDescription = description;
|
||||
mLinkColor = linkColor;
|
||||
mBackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SingleResponse<ParcelableUser> doLongOperation(final Object params) {
|
||||
final ParcelableCredentials credentials = ParcelableCredentialsUtils.getCredentials(mActivity, mAccountKey);
|
||||
if (credentials == null) return SingleResponse.getInstance();
|
||||
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mActivity, credentials,
|
||||
true, true);
|
||||
if (twitter == null) return SingleResponse.getInstance();
|
||||
try {
|
||||
User user = null;
|
||||
if (isProfileChanged()) {
|
||||
final ProfileUpdate profileUpdate = new ProfileUpdate();
|
||||
profileUpdate.name(HtmlEscapeHelper.escapeBasic(mName));
|
||||
profileUpdate.location(HtmlEscapeHelper.escapeBasic(mLocation));
|
||||
profileUpdate.description(HtmlEscapeHelper.escapeBasic(mDescription));
|
||||
profileUpdate.url(mUrl);
|
||||
profileUpdate.linkColor(mLinkColor);
|
||||
profileUpdate.backgroundColor(mBackgroundColor);
|
||||
user = twitter.updateProfile(profileUpdate);
|
||||
}
|
||||
if (user == null) {
|
||||
// User profile unchanged
|
||||
return SingleResponse.getInstance();
|
||||
}
|
||||
final SingleResponse<ParcelableUser> response = SingleResponse.getInstance(
|
||||
ParcelableUserUtils.fromUser(user, mAccountKey));
|
||||
response.getExtras().putParcelable(EXTRA_ACCOUNT, credentials);
|
||||
return response;
|
||||
} catch (MicroBlogException e) {
|
||||
return SingleResponse.getInstance(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProfileChanged() {
|
||||
final ParcelableUser orig = mOriginal;
|
||||
if (orig == null) return true;
|
||||
if (mLinkColor != orig.link_color) return true;
|
||||
if (mBackgroundColor != orig.background_color) return true;
|
||||
if (!stringEquals(mName, orig.name)) return true;
|
||||
if (!stringEquals(mDescription, ParcelableUserUtils.getExpandedDescription(orig)))
|
||||
return true;
|
||||
if (!stringEquals(mLocation, orig.location)) return true;
|
||||
if (!stringEquals(mUrl, isEmpty(orig.url_expanded) ? orig.url : orig.url_expanded))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(UserProfileEditorFragment callback, SingleResponse<ParcelableUser> result) {
|
||||
super.afterExecute(callback, result);
|
||||
if (result.hasData()) {
|
||||
final ParcelableAccount account = result.getExtras().getParcelable(EXTRA_ACCOUNT);
|
||||
if (account != null) {
|
||||
final UpdateAccountInfoTask task = new UpdateAccountInfoTask(mActivity);
|
||||
task.setParams(Pair.create(account, result.getData()));
|
||||
TaskStarter.execute(task);
|
||||
}
|
||||
}
|
||||
callback.executeAfterFragmentResumed(new Action() {
|
||||
@Override
|
||||
public void execute(IBaseFragment fragment) {
|
||||
final Fragment f = ((UserProfileEditorFragment) fragment).getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG);
|
||||
if (f instanceof DialogFragment) {
|
||||
((DialogFragment) f).dismissAllowingStateLoss();
|
||||
}
|
||||
f.getActivity().finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute() {
|
||||
super.beforeExecute();
|
||||
final UserProfileEditorFragment callback = getCallback();
|
||||
if (callback != null) {
|
||||
callback.executeAfterFragmentResumed(new Action() {
|
||||
@Override
|
||||
public void execute(IBaseFragment fragment) {
|
||||
final DialogFragment df = ProgressDialogFragment.show(((UserProfileEditorFragment) fragment).getActivity(), DIALOG_FRAGMENT_TAG);
|
||||
df.setCancelable(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RemoveProfileBannerTaskInternal extends AbstractTask<Object, SingleResponse<Boolean>, UserProfileEditorFragment> {
|
||||
|
||||
private final UserKey mAccountKey;
|
||||
|
||||
RemoveProfileBannerTaskInternal(final UserKey accountKey) {
|
||||
this.mAccountKey = accountKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SingleResponse<Boolean> doLongOperation(final Object params) {
|
||||
return TwitterWrapper.deleteProfileBannerImage(getActivity(), mAccountKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(UserProfileEditorFragment callback, final SingleResponse<Boolean> result) {
|
||||
super.afterExecute(callback, result);
|
||||
if (result.getData() != null && result.getData()) {
|
||||
getUserInfo();
|
||||
Toast.makeText(getActivity(), R.string.profile_banner_image_updated, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Utils.showErrorMessage(getActivity(), R.string.action_removing_profile_banner_image,
|
||||
result.getException(), true);
|
||||
}
|
||||
setUpdateState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute() {
|
||||
super.beforeExecute();
|
||||
setUpdateState(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateProfileBannerImageTaskInternal extends UpdateProfileBannerImageTask<UserProfileEditorFragment> {
|
||||
|
||||
public UpdateProfileBannerImageTaskInternal(final Context context, final UserKey accountKey,
|
||||
final Uri imageUri, final boolean deleteImage) {
|
||||
super(context, accountKey, imageUri, deleteImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(UserProfileEditorFragment callback, final SingleResponse<ParcelableUser> result) {
|
||||
super.afterExecute(callback, result);
|
||||
setUpdateState(false);
|
||||
getUserInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute() {
|
||||
super.beforeExecute();
|
||||
setUpdateState(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateProfileBackgroundImageTaskInternal extends UpdateProfileBackgroundImageTask<UserProfileEditorFragment> {
|
||||
|
||||
public UpdateProfileBackgroundImageTaskInternal(final Context context, final UserKey accountKey,
|
||||
final Uri imageUri, final boolean tile,
|
||||
final boolean deleteImage) {
|
||||
super(context, accountKey, imageUri, tile, deleteImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(UserProfileEditorFragment callback, final SingleResponse<ParcelableUser> result) {
|
||||
super.afterExecute(callback, result);
|
||||
setUpdateState(false);
|
||||
getUserInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute() {
|
||||
super.beforeExecute();
|
||||
setUpdateState(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateProfileImageTaskInternal extends UpdateProfileImageTask<UserProfileEditorFragment> {
|
||||
|
||||
public UpdateProfileImageTaskInternal(final Context context, final UserKey accountKey,
|
||||
final Uri imageUri, final boolean deleteImage) {
|
||||
super(context, accountKey, imageUri, deleteImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(UserProfileEditorFragment callback, SingleResponse<ParcelableUser> result) {
|
||||
super.afterExecute(callback, result);
|
||||
if (result != null && result.getData() != null) {
|
||||
displayUser(result.getData());
|
||||
}
|
||||
setUpdateState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute() {
|
||||
super.beforeExecute();
|
||||
setUpdateState(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,526 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.support.v4.app.DialogFragment
|
||||
import android.support.v4.app.FragmentActivity
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.Loader
|
||||
import android.text.Editable
|
||||
import android.text.TextUtils.isEmpty
|
||||
import android.text.TextWatcher
|
||||
import android.view.*
|
||||
import android.view.View.OnClickListener
|
||||
import android.widget.Toast
|
||||
import com.twitter.Validator
|
||||
import kotlinx.android.synthetic.main.fragment_user_profile_editor.*
|
||||
import org.mariotaku.abstask.library.AbstractTask
|
||||
import org.mariotaku.abstask.library.TaskStarter
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.twitter.model.ProfileUpdate
|
||||
import org.mariotaku.microblog.library.twitter.model.User
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
|
||||
import org.mariotaku.twidere.activity.ThemedImagePickerActivity
|
||||
import org.mariotaku.twidere.loader.ParcelableUserLoader
|
||||
import org.mariotaku.twidere.model.ParcelableAccount
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
import org.mariotaku.twidere.model.SingleResponse
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
||||
import org.mariotaku.twidere.task.UpdateAccountInfoTask
|
||||
import org.mariotaku.twidere.task.UpdateProfileBackgroundImageTask
|
||||
import org.mariotaku.twidere.task.UpdateProfileBannerImageTask
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileImageTask
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener
|
||||
|
||||
class UserProfileEditorFragment : BaseSupportFragment(), OnSizeChangedListener, TextWatcher, OnClickListener, LoaderCallbacks<SingleResponse<ParcelableUser>>, KeyboardShortcutsHandler.TakeAllKeyboardShortcut {
|
||||
|
||||
private var task: AbstractTask<*, *, UserProfileEditorFragment>? = null
|
||||
private val accountKey: UserKey
|
||||
get() = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
private var user: ParcelableUser? = null
|
||||
private var userInfoLoaderInitialized: Boolean = false
|
||||
private var getUserInfoCalled: Boolean = false
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, length: Int, start: Int, end: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, length: Int, start: Int, end: Int) {
|
||||
updateDoneButton()
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
}
|
||||
|
||||
override fun onClick(view: View) {
|
||||
val user = user
|
||||
if (user == null || task != null && !task!!.isFinished)
|
||||
return
|
||||
when (view.id) {
|
||||
R.id.profile_image -> {
|
||||
}
|
||||
R.id.profileBanner -> {
|
||||
}
|
||||
R.id.editProfileImage -> {
|
||||
val intent = ThemedImagePickerActivity.withThemed(activity).aspectRatio(1, 1).maximumSize(512, 512).build()
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_IMAGE)
|
||||
}
|
||||
R.id.editProfileBanner -> {
|
||||
val intent = ThemedImagePickerActivity.withThemed(activity).aspectRatio(3, 1).maximumSize(1500, 500).addEntry(getString(R.string.remove), "remove_banner", RESULT_REMOVE_BANNER).build()
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BANNER_IMAGE)
|
||||
}
|
||||
R.id.editProfileBackground -> {
|
||||
val intent = ThemedImagePickerActivity.withThemed(activity).build()
|
||||
startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE)
|
||||
}
|
||||
R.id.setLinkColor -> {
|
||||
val intent = Intent(activity, ColorPickerDialogActivity::class.java)
|
||||
intent.putExtra(EXTRA_COLOR, user.link_color)
|
||||
intent.putExtra(EXTRA_ALPHA_SLIDER, false)
|
||||
startActivityForResult(intent, REQUEST_PICK_LINK_COLOR)
|
||||
}
|
||||
R.id.setBackgroundColor -> {
|
||||
val intent = Intent(activity, ColorPickerDialogActivity::class.java)
|
||||
intent.putExtra(EXTRA_COLOR, user.background_color)
|
||||
intent.putExtra(EXTRA_ALPHA_SLIDER, false)
|
||||
startActivityForResult(intent, REQUEST_PICK_BACKGROUND_COLOR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<SingleResponse<ParcelableUser>> {
|
||||
progressContainer!!.visibility = View.VISIBLE
|
||||
editProfileContent!!.visibility = View.GONE
|
||||
return ParcelableUserLoader(activity, accountKey, accountKey, null, arguments,
|
||||
false, false)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableUser>>,
|
||||
data: SingleResponse<ParcelableUser>) {
|
||||
if (data.data != null && data.data.key != null) {
|
||||
displayUser(data.data)
|
||||
} else if (user == null) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableUser>>) {
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater!!.inflate(R.menu.menu_profile_editor, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item!!.itemId) {
|
||||
R.id.save -> {
|
||||
val name = ParseUtils.parseString(editName!!.text)
|
||||
val url = ParseUtils.parseString(editUrl.text)
|
||||
val location = ParseUtils.parseString(editLocation!!.text)
|
||||
val description = ParseUtils.parseString(editDescription!!.text)
|
||||
val linkColor = linkColor!!.color
|
||||
val backgroundColor = backgroundColor!!.color
|
||||
task = UpdateProfileTaskInternal(this, accountKey, user, name, url, location,
|
||||
description, linkColor, backgroundColor)
|
||||
TaskStarter.execute(task)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
if (!Utils.isMyAccount(activity, accountKey)) {
|
||||
activity.finish()
|
||||
return
|
||||
}
|
||||
|
||||
val lengthChecker = TwitterValidatorMETLengthChecker(Validator())
|
||||
editName!!.addTextChangedListener(this)
|
||||
editDescription!!.addTextChangedListener(this)
|
||||
editLocation!!.addTextChangedListener(this)
|
||||
editUrl!!.addTextChangedListener(this)
|
||||
|
||||
editDescription!!.setLengthChecker(lengthChecker)
|
||||
|
||||
profileImage!!.setOnClickListener(this)
|
||||
profileBanner!!.setOnClickListener(this)
|
||||
profileBackground!!.setOnClickListener(this)
|
||||
|
||||
editProfileImage!!.setOnClickListener(this)
|
||||
editProfileBanner!!.setOnClickListener(this)
|
||||
editProfileBackground!!.setOnClickListener(this)
|
||||
|
||||
setLinkColor!!.setOnClickListener(this)
|
||||
setBackgroundColor!!.setOnClickListener(this)
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.getParcelable<Parcelable>(EXTRA_USER) != null) {
|
||||
val user = savedInstanceState.getParcelable<ParcelableUser>(EXTRA_USER)!!
|
||||
displayUser(user)
|
||||
editName!!.setText(savedInstanceState.getString(EXTRA_NAME, user.name))
|
||||
editLocation!!.setText(savedInstanceState.getString(EXTRA_LOCATION, user.location))
|
||||
editDescription!!.setText(savedInstanceState.getString(EXTRA_DESCRIPTION, ParcelableUserUtils.getExpandedDescription(user)))
|
||||
editUrl!!.setText(savedInstanceState.getString(EXTRA_URL, user.url_expanded))
|
||||
} else {
|
||||
getUserInfo()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState!!.putParcelable(EXTRA_USER, user)
|
||||
outState.putString(EXTRA_NAME, ParseUtils.parseString(editName!!.text))
|
||||
outState.putString(EXTRA_DESCRIPTION, ParseUtils.parseString(editDescription!!.text))
|
||||
outState.putString(EXTRA_LOCATION, ParseUtils.parseString(editLocation!!.text))
|
||||
outState.putString(EXTRA_URL, ParseUtils.parseString(editUrl!!.text))
|
||||
}
|
||||
|
||||
override fun onSizeChanged(view: View, w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater!!.inflate(R.layout.fragment_user_profile_editor, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == FragmentActivity.RESULT_CANCELED) return
|
||||
when (requestCode) {
|
||||
REQUEST_UPLOAD_PROFILE_BANNER_IMAGE -> {
|
||||
if (task != null && !task!!.isFinished) return
|
||||
if (resultCode == RESULT_REMOVE_BANNER) {
|
||||
task = RemoveProfileBannerTaskInternal(accountKey)
|
||||
} else {
|
||||
task = UpdateProfileBannerImageTaskInternal(activity, accountKey,
|
||||
data!!.data, true)
|
||||
}
|
||||
}
|
||||
REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE -> {
|
||||
//TODO upload profile background
|
||||
if (task != null && !task!!.isFinished) return
|
||||
task = UpdateProfileBackgroundImageTaskInternal(activity, accountKey,
|
||||
data!!.data, false, true)
|
||||
}
|
||||
REQUEST_UPLOAD_PROFILE_IMAGE -> {
|
||||
if (task != null && !task!!.isFinished) return
|
||||
task = UpdateProfileImageTaskInternal(activity, accountKey,
|
||||
data!!.data, true)
|
||||
}
|
||||
REQUEST_PICK_LINK_COLOR -> {
|
||||
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
|
||||
linkColor!!.color = data!!.getIntExtra(EXTRA_COLOR, 0)
|
||||
updateDoneButton()
|
||||
}
|
||||
}
|
||||
REQUEST_PICK_BACKGROUND_COLOR -> {
|
||||
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
|
||||
backgroundColor!!.color = data!!.getIntExtra(EXTRA_COLOR, 0)
|
||||
updateDoneButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun displayUser(user: ParcelableUser?) {
|
||||
if (!getUserInfoCalled) return
|
||||
getUserInfoCalled = false
|
||||
this.user = user
|
||||
if (user != null) {
|
||||
progressContainer!!.visibility = View.GONE
|
||||
editProfileContent!!.visibility = View.VISIBLE
|
||||
editName.setText(user.name)
|
||||
editDescription.setText(ParcelableUserUtils.getExpandedDescription(user))
|
||||
editLocation.setText(user.location)
|
||||
editUrl.setText(if (isEmpty(user.url_expanded)) user.url else user.url_expanded)
|
||||
mediaLoader.displayProfileImage(profileImage, user)
|
||||
val defWidth = resources.displayMetrics.widthPixels
|
||||
mediaLoader.displayProfileBanner(profileBanner, user.profile_banner_url, defWidth)
|
||||
mediaLoader.displayImage(profileBackground, user.profile_background_url)
|
||||
linkColor!!.color = user.link_color
|
||||
backgroundColor!!.color = user.background_color
|
||||
if (USER_TYPE_FANFOU_COM == user.key.host) {
|
||||
editProfileBanner!!.visibility = View.GONE
|
||||
} else {
|
||||
editProfileBanner!!.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
progressContainer!!.visibility = View.GONE
|
||||
editProfileContent!!.visibility = View.GONE
|
||||
}
|
||||
updateDoneButton()
|
||||
}
|
||||
|
||||
private fun getUserInfo() {
|
||||
if (activity == null || isDetached) return
|
||||
val lm = loaderManager
|
||||
lm.destroyLoader(LOADER_ID_USER)
|
||||
getUserInfoCalled = true
|
||||
if (userInfoLoaderInitialized) {
|
||||
lm.restartLoader(LOADER_ID_USER, null, this)
|
||||
} else {
|
||||
lm.initLoader(LOADER_ID_USER, null, this)
|
||||
userInfoLoaderInitialized = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (task != null && !task!!.isFinished) {
|
||||
TaskStarter.execute(task)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dismissDialogFragment(tag: String) {
|
||||
executeAfterFragmentResumed {
|
||||
val fm = childFragmentManager
|
||||
val f = fm.findFragmentByTag(tag)
|
||||
if (f is DialogFragment) {
|
||||
f.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpdateState(start: Boolean) {
|
||||
if (!start) {
|
||||
dismissDialogFragment(UPDATE_PROFILE_DIALOG_FRAGMENT_TAG)
|
||||
return
|
||||
}
|
||||
executeAfterFragmentResumed {
|
||||
val fm = childFragmentManager
|
||||
val df = ProgressDialogFragment()
|
||||
df.show(fm, UPDATE_PROFILE_DIALOG_FRAGMENT_TAG)
|
||||
df.isCancelable = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDoneButton() {
|
||||
|
||||
}
|
||||
|
||||
internal class UpdateProfileTaskInternal(
|
||||
fragment: UserProfileEditorFragment,
|
||||
private val accountKey: UserKey,
|
||||
private val original: ParcelableUser?,
|
||||
private val name: String,
|
||||
private val url: String,
|
||||
private val location: String,
|
||||
private val description: String,
|
||||
private val linkColor: Int,
|
||||
private val backgroundColor: Int
|
||||
) : AbstractTask<Any, SingleResponse<ParcelableUser>, UserProfileEditorFragment>() {
|
||||
private val activity: FragmentActivity
|
||||
|
||||
init {
|
||||
activity = fragment.activity
|
||||
}
|
||||
|
||||
override fun doLongOperation(params: Any): SingleResponse<ParcelableUser> {
|
||||
val credentials = ParcelableCredentialsUtils.getCredentials(activity, accountKey) ?: return SingleResponse.getInstance<ParcelableUser>()
|
||||
val twitter = MicroBlogAPIFactory.getInstance(activity, credentials,
|
||||
true, true) ?: return SingleResponse.getInstance<ParcelableUser>()
|
||||
try {
|
||||
var user: User? = null
|
||||
if (isProfileChanged) {
|
||||
val profileUpdate = ProfileUpdate()
|
||||
profileUpdate.name(HtmlEscapeHelper.escapeBasic(name))
|
||||
profileUpdate.location(HtmlEscapeHelper.escapeBasic(location))
|
||||
profileUpdate.description(HtmlEscapeHelper.escapeBasic(description))
|
||||
profileUpdate.url(url)
|
||||
profileUpdate.linkColor(linkColor)
|
||||
profileUpdate.backgroundColor(backgroundColor)
|
||||
user = twitter.updateProfile(profileUpdate)
|
||||
}
|
||||
if (user == null) {
|
||||
// User profile unchanged
|
||||
return SingleResponse.getInstance<ParcelableUser>()
|
||||
}
|
||||
val response = SingleResponse.getInstance(
|
||||
ParcelableUserUtils.fromUser(user, accountKey))
|
||||
response.extras.putParcelable(EXTRA_ACCOUNT, credentials)
|
||||
return response
|
||||
} catch (e: MicroBlogException) {
|
||||
return SingleResponse.getInstance<ParcelableUser>(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val isProfileChanged: Boolean
|
||||
get() {
|
||||
val orig = original ?: return true
|
||||
if (linkColor != orig.link_color) return true
|
||||
if (backgroundColor != orig.background_color) return true
|
||||
if (!stringEquals(name, orig.name)) return true
|
||||
if (!stringEquals(description, ParcelableUserUtils.getExpandedDescription(orig)))
|
||||
return true
|
||||
if (!stringEquals(location, orig.location)) return true
|
||||
if (!stringEquals(url, if (isEmpty(orig.url_expanded)) orig.url else orig.url_expanded))
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse<ParcelableUser>?) {
|
||||
super.afterExecute(callback, result)
|
||||
if (result!!.hasData()) {
|
||||
val account = result.extras.getParcelable<ParcelableAccount>(EXTRA_ACCOUNT)
|
||||
if (account != null) {
|
||||
val task = UpdateAccountInfoTask(activity)
|
||||
task.setParams(Pair(account, result.data))
|
||||
TaskStarter.execute(task)
|
||||
}
|
||||
}
|
||||
callback!!.executeAfterFragmentResumed { fragment ->
|
||||
val f = (fragment as UserProfileEditorFragment).fragmentManager.findFragmentByTag(DIALOG_FRAGMENT_TAG)
|
||||
if (f is DialogFragment) {
|
||||
f.dismissAllowingStateLoss()
|
||||
}
|
||||
f.activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeExecute() {
|
||||
super.beforeExecute()
|
||||
val callback = callback
|
||||
callback?.executeAfterFragmentResumed { fragment ->
|
||||
val df = ProgressDialogFragment.show((fragment as UserProfileEditorFragment).activity, DIALOG_FRAGMENT_TAG)
|
||||
df.isCancelable = false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val DIALOG_FRAGMENT_TAG = "updating_user_profile"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal inner class RemoveProfileBannerTaskInternal(private val accountKey: UserKey) : AbstractTask<Any, SingleResponse<Boolean>, UserProfileEditorFragment>() {
|
||||
|
||||
override fun doLongOperation(params: Any): SingleResponse<Boolean> {
|
||||
return TwitterWrapper.deleteProfileBannerImage(activity, accountKey)
|
||||
}
|
||||
|
||||
override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse<Boolean>?) {
|
||||
super.afterExecute(callback, result)
|
||||
if (result!!.data != null && result.data) {
|
||||
getUserInfo()
|
||||
Toast.makeText(activity, R.string.profile_banner_image_updated, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Utils.showErrorMessage(activity, R.string.action_removing_profile_banner_image,
|
||||
result.exception, true)
|
||||
}
|
||||
setUpdateState(false)
|
||||
}
|
||||
|
||||
override fun beforeExecute() {
|
||||
super.beforeExecute()
|
||||
setUpdateState(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private inner class UpdateProfileBannerImageTaskInternal(context: Context, accountKey: UserKey,
|
||||
imageUri: Uri, deleteImage: Boolean) : UpdateProfileBannerImageTask<UserProfileEditorFragment>(context, accountKey, imageUri, deleteImage) {
|
||||
|
||||
override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse<ParcelableUser>?) {
|
||||
super.afterExecute(callback, result)
|
||||
setUpdateState(false)
|
||||
getUserInfo()
|
||||
}
|
||||
|
||||
override fun beforeExecute() {
|
||||
super.beforeExecute()
|
||||
setUpdateState(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private inner class UpdateProfileBackgroundImageTaskInternal(context: Context, accountKey: UserKey,
|
||||
imageUri: Uri, tile: Boolean,
|
||||
deleteImage: Boolean) : UpdateProfileBackgroundImageTask<UserProfileEditorFragment>(context, accountKey, imageUri, tile, deleteImage) {
|
||||
|
||||
override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse<ParcelableUser>?) {
|
||||
super.afterExecute(callback, result)
|
||||
setUpdateState(false)
|
||||
getUserInfo()
|
||||
}
|
||||
|
||||
override fun beforeExecute() {
|
||||
super.beforeExecute()
|
||||
setUpdateState(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private inner class UpdateProfileImageTaskInternal(context: Context, accountKey: UserKey,
|
||||
imageUri: Uri, deleteImage: Boolean) : UpdateProfileImageTask<UserProfileEditorFragment>(context, accountKey, imageUri, deleteImage) {
|
||||
|
||||
override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse<ParcelableUser>?) {
|
||||
super.afterExecute(callback, result)
|
||||
if (result != null && result.data != null) {
|
||||
displayUser(result.data)
|
||||
}
|
||||
setUpdateState(false)
|
||||
}
|
||||
|
||||
override fun beforeExecute() {
|
||||
super.beforeExecute()
|
||||
setUpdateState(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val LOADER_ID_USER = 1
|
||||
|
||||
private val REQUEST_UPLOAD_PROFILE_IMAGE = 1
|
||||
private val REQUEST_UPLOAD_PROFILE_BANNER_IMAGE = 2
|
||||
private val REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE = 3
|
||||
private val REQUEST_PICK_LINK_COLOR = 11
|
||||
private val REQUEST_PICK_BACKGROUND_COLOR = 12
|
||||
|
||||
private val RESULT_REMOVE_BANNER = 101
|
||||
private val UPDATE_PROFILE_DIALOG_FRAGMENT_TAG = "update_profile"
|
||||
|
||||
private fun stringEquals(str1: CharSequence?, str2: CharSequence?): Boolean {
|
||||
if (str1 == null || str2 == null) return str1 === str2
|
||||
if (str1.length != str2.length) return false
|
||||
var i = 0
|
||||
val j = str1.length
|
||||
while (i < j) {
|
||||
if (str1[i] != str2[i]) return false
|
||||
i++
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
@ -180,7 +180,7 @@ public abstract class MicroBlogAPIStatusesLoader extends ParcelableStatusesLoade
|
||||
data.add(item);
|
||||
}
|
||||
|
||||
final SQLiteDatabase db = TwidereApplication.getInstance(context).getSQLiteDatabase();
|
||||
final SQLiteDatabase db = TwidereApplication.Companion.getInstance(context).getSqLiteDatabase();
|
||||
final ParcelableStatus[] array = data.toArray(new ParcelableStatus[data.size()]);
|
||||
for (int i = 0, size = array.length; i < size; i++) {
|
||||
final ParcelableStatus status = array[i];
|
||||
|
@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.loader;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.mariotaku.abstask.library.TaskStarter;
|
||||
import org.mariotaku.microblog.library.MicroBlog;
|
||||
import org.mariotaku.microblog.library.MicroBlogException;
|
||||
import org.mariotaku.microblog.library.twitter.model.User;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.annotation.Referral;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserCursorIndices;
|
||||
import org.mariotaku.twidere.model.ParcelableUserValuesCreator;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.task.UpdateAccountInfoTask;
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.mariotaku.twidere.util.ContentValuesCreator.createCachedUser;
|
||||
|
||||
public final class ParcelableUserLoader extends AsyncTaskLoader<SingleResponse<ParcelableUser>>
|
||||
implements Constants {
|
||||
|
||||
private final boolean mOmitIntentExtra, mLoadFromCache;
|
||||
private final Bundle mExtras;
|
||||
private final UserKey mAccountKey;
|
||||
private final UserKey mUserKey;
|
||||
private final String mScreenName;
|
||||
|
||||
@Inject
|
||||
UserColorNameManager mUserColorNameManager;
|
||||
|
||||
public ParcelableUserLoader(final Context context, final UserKey accountKey,
|
||||
final UserKey userKey, final String screenName,
|
||||
final Bundle extras, final boolean omitIntentExtra,
|
||||
final boolean loadFromCache) {
|
||||
super(context);
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
this.mOmitIntentExtra = omitIntentExtra;
|
||||
this.mLoadFromCache = loadFromCache;
|
||||
this.mExtras = extras;
|
||||
this.mAccountKey = accountKey;
|
||||
this.mUserKey = userKey;
|
||||
this.mScreenName = screenName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<ParcelableUser> loadInBackground() {
|
||||
final Context context = getContext();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final UserKey accountKey = mAccountKey;
|
||||
ParcelableCredentials credentials = null;
|
||||
for (ParcelableCredentials cred : ParcelableCredentialsUtils.getCredentialses(context)) {
|
||||
if (cred.account_key.equals(accountKey)) {
|
||||
credentials = cred;
|
||||
break;
|
||||
} else if (cred.account_user != null && cred.account_user.account_key.equals(accountKey)) {
|
||||
credentials = cred;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (credentials == null) return SingleResponse.getInstance();
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableUser user = mExtras.getParcelable(EXTRA_USER);
|
||||
if (user != null) {
|
||||
final ContentValues values = ParcelableUserValuesCreator.create(user);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, values);
|
||||
ParcelableUserUtils.updateExtraInformation(user, credentials, mUserColorNameManager);
|
||||
return SingleResponse.getInstance(user);
|
||||
}
|
||||
}
|
||||
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(context, credentials, true, true);
|
||||
if (twitter == null) return SingleResponse.getInstance();
|
||||
if (mLoadFromCache) {
|
||||
final Expression where;
|
||||
final String[] whereArgs;
|
||||
if (mUserKey != null) {
|
||||
where = Expression.equalsArgs(CachedUsers.USER_KEY);
|
||||
whereArgs = new String[]{mUserKey.toString()};
|
||||
} else if (mScreenName != null) {
|
||||
final String host = mAccountKey.getHost();
|
||||
if (host != null) {
|
||||
where = Expression.and(
|
||||
Expression.likeRaw(new Columns.Column(CachedUsers.USER_KEY), "'%@'||?"),
|
||||
Expression.equalsArgs(CachedUsers.SCREEN_NAME)
|
||||
);
|
||||
whereArgs = new String[]{host, mScreenName};
|
||||
} else {
|
||||
where = Expression.equalsArgs(CachedUsers.SCREEN_NAME);
|
||||
whereArgs = new String[]{mScreenName};
|
||||
}
|
||||
} else {
|
||||
return SingleResponse.getInstance();
|
||||
}
|
||||
final Cursor cur = resolver.query(CachedUsers.CONTENT_URI, CachedUsers.COLUMNS,
|
||||
where.getSQL(), whereArgs, null);
|
||||
if (cur != null) {
|
||||
try {
|
||||
cur.moveToFirst();
|
||||
final ParcelableUserCursorIndices indices = new ParcelableUserCursorIndices(cur);
|
||||
while (!cur.isAfterLast()) {
|
||||
final ParcelableUser user = indices.newObject(cur);
|
||||
if (TextUtils.equals(UserKeyUtils.getUserHost(user), user.key.getHost())) {
|
||||
user.account_key = accountKey;
|
||||
user.account_color = credentials.color;
|
||||
return SingleResponse.getInstance(user);
|
||||
}
|
||||
cur.moveToNext();
|
||||
}
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
final User twitterUser;
|
||||
if (mExtras != null && Referral.SELF_PROFILE.equals(mExtras.getString(EXTRA_REFERRAL))) {
|
||||
twitterUser = twitter.verifyCredentials();
|
||||
} else {
|
||||
String profileUrl = null;
|
||||
if (mExtras != null) {
|
||||
profileUrl = mExtras.getString(EXTRA_PROFILE_URL);
|
||||
}
|
||||
if (MicroBlogAPIFactory.isStatusNetCredentials(credentials) && mUserKey != null &&
|
||||
profileUrl != null && !TextUtils.equals(credentials.account_key.getHost(),
|
||||
mUserKey.getHost())) {
|
||||
twitterUser = twitter.showExternalProfile(profileUrl);
|
||||
} else {
|
||||
final String id = mUserKey != null ? mUserKey.getId() : null;
|
||||
twitterUser = TwitterWrapper.tryShowUser(twitter, id, mScreenName,
|
||||
credentials.account_type);
|
||||
}
|
||||
}
|
||||
final ContentValues cachedUserValues = createCachedUser(twitterUser);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues);
|
||||
final ParcelableUser user = ParcelableUserUtils.fromUser(twitterUser, accountKey);
|
||||
ParcelableUserUtils.updateExtraInformation(user, credentials, mUserColorNameManager);
|
||||
final SingleResponse<ParcelableUser> response = SingleResponse.getInstance(user);
|
||||
response.getExtras().putParcelable(EXTRA_ACCOUNT, credentials);
|
||||
return response;
|
||||
} catch (final MicroBlogException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return SingleResponse.getInstance(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableUser user = mExtras.getParcelable(EXTRA_USER);
|
||||
if (user != null) {
|
||||
deliverResult(SingleResponse.getInstance(user));
|
||||
}
|
||||
}
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deliverResult(SingleResponse<ParcelableUser> data) {
|
||||
super.deliverResult(data);
|
||||
if (data.hasData()) {
|
||||
final ParcelableUser user = data.getData();
|
||||
if (user.is_cache) return;
|
||||
final ParcelableAccount account = data.getExtras().getParcelable(EXTRA_ACCOUNT);
|
||||
if (account != null) {
|
||||
final UpdateAccountInfoTask task = new UpdateAccountInfoTask(getContext());
|
||||
task.setParams(Pair.create(account, user));
|
||||
TaskStarter.execute(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.loader
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.AsyncTaskLoader
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import org.mariotaku.abstask.library.TaskStarter
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.twitter.model.User
|
||||
import org.mariotaku.sqliteqb.library.Columns
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.annotation.Referral
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
|
||||
import org.mariotaku.twidere.task.UpdateAccountInfoTask
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator.createCachedUser
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory
|
||||
import org.mariotaku.twidere.util.TwitterWrapper
|
||||
import org.mariotaku.twidere.util.UserColorNameManager
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class ParcelableUserLoader(
|
||||
context: Context,
|
||||
private val accountKey: UserKey,
|
||||
private val userKey: UserKey?,
|
||||
private val screenName: String?,
|
||||
private val extras: Bundle?,
|
||||
private val omitIntentExtra: Boolean,
|
||||
private val loadFromCache: Boolean
|
||||
) : AsyncTaskLoader<SingleResponse<ParcelableUser>>(context), Constants {
|
||||
|
||||
@Inject
|
||||
lateinit var userColorNameManager: UserColorNameManager
|
||||
|
||||
init {
|
||||
GeneralComponentHelper.build(context).inject(this)
|
||||
}
|
||||
|
||||
override fun loadInBackground(): SingleResponse<ParcelableUser> {
|
||||
val context = context
|
||||
val resolver = context.contentResolver
|
||||
val accountKey = accountKey
|
||||
var credentials: ParcelableCredentials? = null
|
||||
for (cred in ParcelableCredentialsUtils.getCredentialses(context)) {
|
||||
if (cred.account_key == accountKey) {
|
||||
credentials = cred
|
||||
break
|
||||
} else if (cred.account_user != null && cred.account_user!!.account_key == accountKey) {
|
||||
credentials = cred
|
||||
break
|
||||
}
|
||||
}
|
||||
if (credentials == null) return SingleResponse.getInstance<ParcelableUser>()
|
||||
if (!omitIntentExtra && extras != null) {
|
||||
val user = extras.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
if (user != null) {
|
||||
val values = ParcelableUserValuesCreator.create(user)
|
||||
resolver.insert(CachedUsers.CONTENT_URI, values)
|
||||
ParcelableUserUtils.updateExtraInformation(user, credentials, userColorNameManager)
|
||||
return SingleResponse.getInstance(user)
|
||||
}
|
||||
}
|
||||
val twitter = MicroBlogAPIFactory.getInstance(context, credentials, true, true) ?: return SingleResponse.getInstance<ParcelableUser>()
|
||||
if (loadFromCache) {
|
||||
val where: Expression
|
||||
val whereArgs: Array<String>
|
||||
if (userKey != null) {
|
||||
where = Expression.equalsArgs(CachedUsers.USER_KEY)
|
||||
whereArgs = arrayOf(userKey.toString())
|
||||
} else if (screenName != null) {
|
||||
val host = this.accountKey.host
|
||||
if (host != null) {
|
||||
where = Expression.and(
|
||||
Expression.likeRaw(Columns.Column(CachedUsers.USER_KEY), "'%@'||?"),
|
||||
Expression.equalsArgs(CachedUsers.SCREEN_NAME))
|
||||
whereArgs = arrayOf(host, screenName)
|
||||
} else {
|
||||
where = Expression.equalsArgs(CachedUsers.SCREEN_NAME)
|
||||
whereArgs = arrayOf(screenName)
|
||||
}
|
||||
} else {
|
||||
return SingleResponse.getInstance<ParcelableUser>()
|
||||
}
|
||||
val cur = resolver.query(CachedUsers.CONTENT_URI, CachedUsers.COLUMNS,
|
||||
where.sql, whereArgs, null)
|
||||
if (cur != null) {
|
||||
try {
|
||||
cur.moveToFirst()
|
||||
val indices = ParcelableUserCursorIndices(cur)
|
||||
while (!cur.isAfterLast) {
|
||||
val user = indices.newObject(cur)
|
||||
if (TextUtils.equals(UserKeyUtils.getUserHost(user), user.key.host)) {
|
||||
user.account_key = accountKey
|
||||
user.account_color = credentials.color
|
||||
return SingleResponse.getInstance(user)
|
||||
}
|
||||
cur.moveToNext()
|
||||
}
|
||||
} finally {
|
||||
cur.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
val twitterUser: User
|
||||
if (extras != null && Referral.SELF_PROFILE == extras.getString(EXTRA_REFERRAL)) {
|
||||
twitterUser = twitter.verifyCredentials()
|
||||
} else {
|
||||
var profileUrl: String? = null
|
||||
if (extras != null) {
|
||||
profileUrl = extras.getString(EXTRA_PROFILE_URL)
|
||||
}
|
||||
if (MicroBlogAPIFactory.isStatusNetCredentials(credentials) && userKey != null &&
|
||||
profileUrl != null && !TextUtils.equals(credentials.account_key.host,
|
||||
userKey.host)) {
|
||||
twitterUser = twitter.showExternalProfile(profileUrl)
|
||||
} else {
|
||||
val id = userKey?.id
|
||||
twitterUser = TwitterWrapper.tryShowUser(twitter, id, screenName,
|
||||
credentials.account_type)
|
||||
}
|
||||
}
|
||||
val cachedUserValues = createCachedUser(twitterUser)
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues)
|
||||
val user = ParcelableUserUtils.fromUser(twitterUser, accountKey)
|
||||
ParcelableUserUtils.updateExtraInformation(user, credentials, userColorNameManager)
|
||||
val response = SingleResponse.getInstance(user)
|
||||
response.extras.putParcelable(EXTRA_ACCOUNT, credentials)
|
||||
return response
|
||||
} catch (e: MicroBlogException) {
|
||||
Log.w(LOGTAG, e)
|
||||
return SingleResponse.getInstance<ParcelableUser>(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onStartLoading() {
|
||||
if (!omitIntentExtra && extras != null) {
|
||||
val user = extras.getParcelable<ParcelableUser>(EXTRA_USER)
|
||||
if (user != null) {
|
||||
deliverResult(SingleResponse.getInstance(user))
|
||||
}
|
||||
}
|
||||
forceLoad()
|
||||
}
|
||||
|
||||
override fun deliverResult(data: SingleResponse<ParcelableUser>) {
|
||||
super.deliverResult(data)
|
||||
if (data.hasData()) {
|
||||
val user = data.data
|
||||
if (user.is_cache) return
|
||||
val account = data.extras.getParcelable<ParcelableAccount>(EXTRA_ACCOUNT)
|
||||
if (account != null) {
|
||||
val task = UpdateAccountInfoTask(context)
|
||||
task.setParams(Pair(account, user))
|
||||
TaskStarter.execute<Pair<ParcelableAccount, ParcelableUser>, Any, Any>(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.menu;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.view.ActionProvider;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
|
||||
import static org.mariotaku.twidere.Constants.MENU_GROUP_STATUS_SHARE;
|
||||
import static org.mariotaku.twidere.util.Utils.createStatusShareIntent;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/7.
|
||||
*/
|
||||
public class SupportStatusShareProvider extends ActionProvider {
|
||||
|
||||
private final Context mContext;
|
||||
private ParcelableStatus mStatus;
|
||||
|
||||
public SupportStatusShareProvider(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateActionView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateActionView(MenuItem forItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPerformDefaultAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSubMenu() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareSubMenu(SubMenu subMenu) {
|
||||
final ParcelableStatus status = mStatus;
|
||||
if (status == null) return;
|
||||
final Intent shareIntent = createStatusShareIntent(mContext, status);
|
||||
subMenu.removeGroup(MENU_GROUP_STATUS_SHARE);
|
||||
MenuUtils.addIntentToMenu(mContext, subMenu, shareIntent, MENU_GROUP_STATUS_SHARE);
|
||||
}
|
||||
|
||||
public void setStatus(ParcelableStatus status) {
|
||||
mStatus = status;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.menu
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v4.view.ActionProvider
|
||||
import android.view.MenuItem
|
||||
import android.view.SubMenu
|
||||
import android.view.View
|
||||
import org.mariotaku.twidere.Constants.MENU_GROUP_STATUS_SHARE
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.util.MenuUtils
|
||||
import org.mariotaku.twidere.util.Utils.createStatusShareIntent
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/7.
|
||||
*/
|
||||
class SupportStatusShareProvider(context: Context) : ActionProvider(context) {
|
||||
var status: ParcelableStatus? = null
|
||||
|
||||
override fun onCreateActionView(): View? = null
|
||||
|
||||
override fun onCreateActionView(forItem: MenuItem?): View? = null
|
||||
|
||||
override fun onPerformDefaultAction(): Boolean = true
|
||||
|
||||
override fun hasSubMenu(): Boolean = true
|
||||
|
||||
override fun onPrepareSubMenu(subMenu: SubMenu?) {
|
||||
val status = status ?: return
|
||||
val shareIntent = createStatusShareIntent(context, status)
|
||||
subMenu!!.removeGroup(MENU_GROUP_STATUS_SHARE)
|
||||
MenuUtils.addIntentToMenu(context, subMenu, shareIntent, MENU_GROUP_STATUS_SHARE)
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
/**
|
||||
* Created by mariotaku on 16/3/6.
|
||||
*/
|
||||
@CursorObject(valuesCreator = true)
|
||||
@CursorObject(valuesCreator = true, tableInfo = true)
|
||||
@JsonObject
|
||||
public class Tab {
|
||||
@CursorField(value = Tabs._ID, excludeWrite = true)
|
||||
|
@ -604,8 +604,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||
|
||||
@Override
|
||||
public SQLiteDatabase onCreateSQLiteDatabase() {
|
||||
final TwidereApplication app = TwidereApplication.getInstance(getContext());
|
||||
final SQLiteOpenHelper helper = app.getSQLiteOpenHelper();
|
||||
final TwidereApplication app = TwidereApplication.Companion.getInstance(getContext());
|
||||
final SQLiteOpenHelper helper = app.getSqLiteOpenHelper();
|
||||
return helper.getWritableDatabase();
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ public class ConnectivityStateReceiver extends BroadcastReceiver implements Cons
|
||||
Log.d(RECEIVER_LOGTAG, String.format("Received Broadcast %s", intent));
|
||||
}
|
||||
if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) return;
|
||||
final TwidereApplication application = TwidereApplication.getInstance(context);
|
||||
final TwidereApplication application = TwidereApplication.Companion.getInstance(context);
|
||||
// application.reloadConnectivitySettings();
|
||||
Utils.startRefreshServiceIfNeeded(application);
|
||||
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
|
||||
|
@ -7,7 +7,6 @@ import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.mariotaku.abstask.library.AbstractTask;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
@ -27,6 +26,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
|
||||
import kotlin.Pair;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/8.
|
||||
*/
|
||||
@ -40,8 +41,8 @@ public class UpdateAccountInfoTask extends AbstractTask<Pair<ParcelableAccount,
|
||||
@Override
|
||||
protected Object doLongOperation(Pair<ParcelableAccount, ParcelableUser> params) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final ParcelableAccount account = params.first;
|
||||
final ParcelableUser user = params.second;
|
||||
final ParcelableAccount account = params.getFirst();
|
||||
final ParcelableUser user = params.getSecond();
|
||||
if (account == null || user == null) return null;
|
||||
if (user.is_cache) {
|
||||
return null;
|
||||
|
@ -225,7 +225,7 @@ public abstract class GetStatusesTask extends AbstractTask<RefreshTaskParam,
|
||||
int olderCount = -1;
|
||||
if (minPositionKey > 0) {
|
||||
olderCount = DataStoreUtils.getStatusesCount(context, uri, null, minPositionKey,
|
||||
Statuses.POSITION_KEY, false, accountKey);
|
||||
Statuses.POSITION_KEY, false, new UserKey[]{accountKey});
|
||||
}
|
||||
final int rowsDeleted = resolver.delete(writeUri, deleteWhere, deleteWhereArgs);
|
||||
|
||||
|
@ -119,7 +119,7 @@ public class UpdateStatusTask extends AbstractTask<Pair<String, ParcelableStatus
|
||||
|
||||
@NonNull
|
||||
private UpdateStatusResult doUpdateStatus(ParcelableStatusUpdate update) throws UpdateStatusException {
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
final TwidereApplication app = TwidereApplication.Companion.getInstance(context);
|
||||
final MediaUploaderInterface uploader = getMediaUploader(app);
|
||||
final StatusShortenerInterface shortener = getStatusShortener(app);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@ -444,6 +445,7 @@ public class DataImportExportUtils implements Constants {
|
||||
this.supportedMap = getSupportedPreferencesMap(cls);
|
||||
}
|
||||
|
||||
@SuppressLint("SwitchIntDef")
|
||||
@Override
|
||||
public boolean importValue(JsonParser jsonParser, String key, SharedPreferences.Editor editor) throws IOException {
|
||||
final JsonToken token = jsonParser.nextToken();
|
||||
@ -478,6 +480,7 @@ public class DataImportExportUtils implements Constants {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressLint("SwitchIntDef")
|
||||
@Override
|
||||
public boolean exportValue(JsonGenerator jsonGenerator, String key, SharedPreferences preferences) throws IOException {
|
||||
final Preference preference = supportedMap.get(key);
|
||||
|
@ -470,7 +470,8 @@ public class DataStoreUtils implements Constants {
|
||||
|
||||
public static int getStatusesCount(@NonNull final Context context, final Uri uri,
|
||||
@Nullable final Bundle extraArgs, final long compare,
|
||||
String compareColumn, boolean greaterThan, UserKey... accountKeys) {
|
||||
String compareColumn, boolean greaterThan,
|
||||
@Nullable UserKey[] accountKeys) {
|
||||
if (accountKeys == null) {
|
||||
accountKeys = getActivatedAccountKeys(context);
|
||||
}
|
||||
|
@ -1,374 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.ActionProvider;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.widget.ShareActionProvider;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.AccountSelectorActivity;
|
||||
import org.mariotaku.twidere.activity.ColorPickerDialogActivity;
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
|
||||
import org.mariotaku.twidere.fragment.AbsStatusesFragment;
|
||||
import org.mariotaku.twidere.fragment.AddStatusFilterDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.DestroyStatusDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.SetUserNicknameDialogFragment;
|
||||
import org.mariotaku.twidere.graphic.ActionIconDrawable;
|
||||
import org.mariotaku.twidere.graphic.PaddingDrawable;
|
||||
import org.mariotaku.twidere.menu.FavoriteItemProvider;
|
||||
import org.mariotaku.twidere.menu.SupportStatusShareProvider;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/4/12.
|
||||
*/
|
||||
public class MenuUtils implements Constants {
|
||||
private MenuUtils() {
|
||||
}
|
||||
|
||||
public static void setMenuItemAvailability(final Menu menu, final int id, final boolean available) {
|
||||
if (menu == null) return;
|
||||
final MenuItem item = menu.findItem(id);
|
||||
if (item == null) return;
|
||||
item.setVisible(available);
|
||||
item.setEnabled(available);
|
||||
}
|
||||
|
||||
public static void setMenuItemChecked(final Menu menu, final int id, final boolean checked) {
|
||||
if (menu == null) return;
|
||||
final MenuItem item = menu.findItem(id);
|
||||
if (item == null) return;
|
||||
item.setChecked(checked);
|
||||
}
|
||||
|
||||
public static void setMenuItemIcon(final Menu menu, final int id, @DrawableRes final int icon) {
|
||||
if (menu == null) return;
|
||||
final MenuItem item = menu.findItem(id);
|
||||
if (item == null) return;
|
||||
item.setIcon(icon);
|
||||
}
|
||||
|
||||
public static void setMenuItemShowAsActionFlags(Menu menu, int id, int flags) {
|
||||
if (menu == null) return;
|
||||
final MenuItem item = menu.findItem(id);
|
||||
if (item == null) return;
|
||||
item.setShowAsActionFlags(flags);
|
||||
MenuItemCompat.setShowAsAction(item, flags);
|
||||
}
|
||||
|
||||
public static void setMenuItemTitle(final Menu menu, final int id, @StringRes final int icon) {
|
||||
if (menu == null) return;
|
||||
final MenuItem item = menu.findItem(id);
|
||||
if (item == null) return;
|
||||
item.setTitle(icon);
|
||||
}
|
||||
|
||||
public static void addIntentToMenu(final Context context, final Menu menu, final Intent queryIntent) {
|
||||
addIntentToMenu(context, menu, queryIntent, Menu.NONE);
|
||||
}
|
||||
|
||||
public static void addIntentToMenu(final Context context, final Menu menu, final Intent queryIntent,
|
||||
final int groupId) {
|
||||
if (context == null || menu == null || queryIntent == null) return;
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
final Resources res = context.getResources();
|
||||
final float density = res.getDisplayMetrics().density;
|
||||
final int padding = Math.round(density * 4);
|
||||
final List<ResolveInfo> activities = pm.queryIntentActivities(queryIntent, 0);
|
||||
for (final ResolveInfo info : activities) {
|
||||
final Intent intent = new Intent(queryIntent);
|
||||
final Drawable icon = info.loadIcon(pm);
|
||||
intent.setClassName(info.activityInfo.packageName, info.activityInfo.name);
|
||||
final MenuItem item = menu.add(groupId, Menu.NONE, Menu.NONE, info.loadLabel(pm));
|
||||
item.setIntent(intent);
|
||||
final int iw = icon.getIntrinsicWidth(), ih = icon.getIntrinsicHeight();
|
||||
if (iw > 0 && ih > 0) {
|
||||
final Drawable iconWithPadding = new PaddingDrawable(icon, padding);
|
||||
iconWithPadding.setBounds(0, 0, iw, ih);
|
||||
item.setIcon(iconWithPadding);
|
||||
} else {
|
||||
item.setIcon(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupForStatus(@NonNull final Context context,
|
||||
@NonNull final SharedPreferencesWrapper preferences,
|
||||
@NonNull final Menu menu,
|
||||
@NonNull final ParcelableStatus status,
|
||||
@NonNull final AsyncTwitterWrapper twitter) {
|
||||
final ParcelableCredentials account = ParcelableCredentialsUtils.getCredentials(context,
|
||||
status.account_key);
|
||||
if (account == null) return;
|
||||
setupForStatus(context, preferences, menu, status, account, twitter);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public static void setupForStatus(@NonNull final Context context,
|
||||
@NonNull final SharedPreferencesWrapper preferences,
|
||||
@NonNull final Menu menu,
|
||||
@NonNull final ParcelableStatus status,
|
||||
@NonNull final ParcelableCredentials account,
|
||||
@NonNull final AsyncTwitterWrapper twitter) {
|
||||
if (menu instanceof ContextMenu) {
|
||||
((ContextMenu) menu).setHeaderTitle(context.getString(R.string.status_menu_title_format,
|
||||
UserColorNameManager.decideDisplayName(status.user_nickname, status.user_name,
|
||||
status.user_screen_name, preferences.getBoolean(KEY_NAME_FIRST)),
|
||||
status.text_unescaped));
|
||||
}
|
||||
final int retweetHighlight = ContextCompat.getColor(context, R.color.highlight_retweet);
|
||||
final int favoriteHighlight = ContextCompat.getColor(context, R.color.highlight_favorite);
|
||||
final int likeHighlight = ContextCompat.getColor(context, R.color.highlight_like);
|
||||
final boolean isMyRetweet;
|
||||
if (twitter.isCreatingRetweet(status.account_key, status.id)) {
|
||||
isMyRetweet = true;
|
||||
} else if (twitter.isDestroyingStatus(status.account_key, status.id)) {
|
||||
isMyRetweet = false;
|
||||
} else {
|
||||
isMyRetweet = status.retweeted || Utils.isMyRetweet(status);
|
||||
}
|
||||
final MenuItem delete = menu.findItem(R.id.delete);
|
||||
if (delete != null) {
|
||||
delete.setVisible(Utils.isMyStatus(status));
|
||||
}
|
||||
final MenuItem retweet = menu.findItem(R.id.retweet);
|
||||
if (retweet != null) {
|
||||
ActionIconDrawable.setMenuHighlight(retweet, new TwidereMenuInfo(isMyRetweet, retweetHighlight));
|
||||
retweet.setTitle(isMyRetweet ? R.string.cancel_retweet : R.string.retweet);
|
||||
}
|
||||
final MenuItem favorite = menu.findItem(R.id.favorite);
|
||||
if (favorite != null) {
|
||||
final boolean isFavorite;
|
||||
if (twitter.isCreatingFavorite(status.account_key, status.id)) {
|
||||
isFavorite = true;
|
||||
} else if (twitter.isDestroyingFavorite(status.account_key, status.id)) {
|
||||
isFavorite = false;
|
||||
} else {
|
||||
isFavorite = status.is_favorite;
|
||||
}
|
||||
ActionProvider provider = MenuItemCompat.getActionProvider(favorite);
|
||||
final boolean useStar = preferences.getBoolean(SharedPreferenceConstants.KEY_I_WANT_MY_STARS_BACK);
|
||||
if (provider instanceof FavoriteItemProvider) {
|
||||
((FavoriteItemProvider) provider).setIsFavorite(favorite, isFavorite);
|
||||
} else {
|
||||
if (useStar) {
|
||||
final Drawable oldIcon = favorite.getIcon();
|
||||
if (oldIcon instanceof ActionIconDrawable) {
|
||||
final Drawable starIcon = ContextCompat.getDrawable(context, R.drawable.ic_action_star);
|
||||
favorite.setIcon(new ActionIconDrawable(starIcon, ((ActionIconDrawable) oldIcon).getDefaultColor()));
|
||||
} else {
|
||||
favorite.setIcon(R.drawable.ic_action_star);
|
||||
}
|
||||
ActionIconDrawable.setMenuHighlight(favorite, new TwidereMenuInfo(isFavorite, favoriteHighlight));
|
||||
} else {
|
||||
ActionIconDrawable.setMenuHighlight(favorite, new TwidereMenuInfo(isFavorite, likeHighlight));
|
||||
}
|
||||
}
|
||||
if (useStar) {
|
||||
favorite.setTitle(isFavorite ? R.string.unfavorite : R.string.favorite);
|
||||
} else {
|
||||
favorite.setTitle(isFavorite ? R.string.undo_like : R.string.like);
|
||||
}
|
||||
}
|
||||
final MenuItem translate = menu.findItem(R.id.translate);
|
||||
if (translate != null) {
|
||||
final boolean isOfficialKey = Utils.isOfficialCredentials(context, account);
|
||||
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
setMenuItemAvailability(menu, R.id.translate, isOfficialKey);
|
||||
}
|
||||
menu.removeGroup(Constants.MENU_GROUP_STATUS_EXTENSION);
|
||||
Utils.addIntentToMenuForExtension(context, menu, Constants.MENU_GROUP_STATUS_EXTENSION, INTENT_ACTION_EXTENSION_OPEN_STATUS,
|
||||
EXTRA_STATUS, EXTRA_STATUS_JSON, status);
|
||||
final MenuItem shareItem = menu.findItem(R.id.share);
|
||||
final ActionProvider shareProvider = MenuItemCompat.getActionProvider(shareItem);
|
||||
if (shareProvider instanceof SupportStatusShareProvider) {
|
||||
((SupportStatusShareProvider) shareProvider).setStatus(status);
|
||||
} else if (shareProvider instanceof ShareActionProvider) {
|
||||
final Intent shareIntent = Utils.createStatusShareIntent(context, status);
|
||||
((ShareActionProvider) shareProvider).setShareIntent(shareIntent);
|
||||
} else if (shareItem.hasSubMenu()) {
|
||||
final Menu shareSubMenu = shareItem.getSubMenu();
|
||||
final Intent shareIntent = Utils.createStatusShareIntent(context, status);
|
||||
shareSubMenu.removeGroup(Constants.MENU_GROUP_STATUS_SHARE);
|
||||
addIntentToMenu(context, shareSubMenu, shareIntent, Constants.MENU_GROUP_STATUS_SHARE);
|
||||
} else {
|
||||
final Intent shareIntent = Utils.createStatusShareIntent(context, status);
|
||||
final Intent chooserIntent = Intent.createChooser(shareIntent, context.getString(R.string.share_status));
|
||||
Utils.addCopyLinkIntent(context, chooserIntent, LinkCreator.getStatusWebLink(status));
|
||||
shareItem.setIntent(chooserIntent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean handleStatusClick(@NonNull final Context context,
|
||||
@Nullable final Fragment fragment,
|
||||
@NonNull final FragmentManager fm,
|
||||
@NonNull final UserColorNameManager colorNameManager,
|
||||
@NonNull final AsyncTwitterWrapper twitter,
|
||||
@NonNull final ParcelableStatus status,
|
||||
@NonNull final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.copy: {
|
||||
if (ClipboardUtils.setText(context, status.text_plain)) {
|
||||
Utils.showOkMessage(context, R.string.text_copied, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.retweet: {
|
||||
if (Utils.isMyRetweet(status)) {
|
||||
twitter.cancelRetweetAsync(status.account_key,
|
||||
status.id, status.my_retweet_id);
|
||||
} else {
|
||||
twitter.retweetStatusAsync(status.account_key,
|
||||
status.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.quote: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
||||
intent.putExtra(EXTRA_STATUS, status);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case R.id.reply: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
||||
intent.putExtra(EXTRA_STATUS, status);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case R.id.favorite: {
|
||||
if (status.is_favorite) {
|
||||
twitter.destroyFavoriteAsync(status.account_key, status.id);
|
||||
} else {
|
||||
ActionProvider provider = MenuItemCompat.getActionProvider(item);
|
||||
if (provider instanceof FavoriteItemProvider) {
|
||||
((FavoriteItemProvider) provider).invokeItem(item,
|
||||
new AbsStatusesFragment.DefaultOnLikedListener(twitter, status));
|
||||
} else {
|
||||
twitter.createFavoriteAsync(status.account_key, status.id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.delete: {
|
||||
DestroyStatusDialogFragment.show(fm, status);
|
||||
break;
|
||||
}
|
||||
case R.id.add_to_filter: {
|
||||
AddStatusFilterDialogFragment.show(fm, status);
|
||||
break;
|
||||
}
|
||||
case R.id.set_color: {
|
||||
final Intent intent = new Intent(context, ColorPickerDialogActivity.class);
|
||||
final int color = colorNameManager.getUserColor(status.user_key);
|
||||
if (color != 0) {
|
||||
intent.putExtra(EXTRA_COLOR, color);
|
||||
}
|
||||
intent.putExtra(EXTRA_CLEAR_BUTTON, color != 0);
|
||||
intent.putExtra(EXTRA_ALPHA_SLIDER, false);
|
||||
if (fragment != null) {
|
||||
fragment.startActivityForResult(intent, REQUEST_SET_COLOR);
|
||||
} else if (context instanceof Activity) {
|
||||
((Activity) context).startActivityForResult(intent, REQUEST_SET_COLOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.clear_nickname: {
|
||||
colorNameManager.clearUserNickname(status.user_key);
|
||||
break;
|
||||
}
|
||||
case R.id.set_nickname: {
|
||||
final String nick = colorNameManager.getUserNickname(status.user_key);
|
||||
final SetUserNicknameDialogFragment df = SetUserNicknameDialogFragment.show(fm,
|
||||
status.user_key, nick);
|
||||
if (fragment != null) {
|
||||
df.setTargetFragment(fragment, REQUEST_SET_NICKNAME);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.open_with_account: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT);
|
||||
intent.setClass(context, AccountSelectorActivity.class);
|
||||
intent.putExtra(EXTRA_SINGLE_SELECTION, true);
|
||||
intent.putExtra(EXTRA_ACCOUNT_HOST, status.user_key.getHost());
|
||||
if (fragment != null) {
|
||||
fragment.startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
|
||||
} else if (context instanceof Activity) {
|
||||
((Activity) context).startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.open_in_browser: {
|
||||
final Uri uri = LinkCreator.getStatusWebLink(status);
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intent.setPackage(IntentUtils.getDefaultBrowserPackage(context, uri, true));
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
intent.setPackage(null);
|
||||
context.startActivity(Intent.createChooser(intent,
|
||||
context.getString(R.string.open_in_browser)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (item.getIntent() != null) {
|
||||
try {
|
||||
context.startActivity(item.getIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user