added border to user type icon
redesigning settings screen removed staggered grid support, will use new implementation soon redesigning direct message entries list
This commit is contained in:
parent
4cc47a3af1
commit
00c0740d38
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 29 KiB |
|
@ -83,7 +83,6 @@ dependencies {
|
||||||
compile 'com.android.support:cardview-v7:21.0.2'
|
compile 'com.android.support:cardview-v7:21.0.2'
|
||||||
compile 'com.android.support:recyclerview-v7:21.0.2'
|
compile 'com.android.support:recyclerview-v7:21.0.2'
|
||||||
compile 'com.android.support:palette-v7:21.0.2'
|
compile 'com.android.support:palette-v7:21.0.2'
|
||||||
compile 'com.etsy.android.grid:library:1.0.5'
|
|
||||||
compile 'com.sothree.slidinguppanel:library:2.0.0'
|
compile 'com.sothree.slidinguppanel:library:2.0.0'
|
||||||
compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
|
compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
|
||||||
compile 'com.twitter:twitter-text:1.9.9'
|
compile 'com.twitter:twitter-text:1.9.9'
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,19 +29,19 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class AllColumns implements Selectable {
|
public class AllColumns implements Selectable {
|
||||||
|
|
||||||
private final String table;
|
private final String table;
|
||||||
|
|
||||||
public AllColumns() {
|
public AllColumns() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AllColumns(final String table) {
|
public AllColumns(final String table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
return table != null ? table + ".*" : "*";
|
return table != null ? table + ".*" : "*";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,64 +29,81 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class Columns implements Selectable {
|
public class Columns implements Selectable {
|
||||||
|
|
||||||
private final AbsColumn[] columns;
|
private final AbsColumn[] columns;
|
||||||
|
|
||||||
public Columns(final AbsColumn... columns) {
|
public Columns(String... columns) {
|
||||||
this.columns = columns;
|
this(Columns.fromStrings(columns));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Columns(final AbsColumn... columns) {
|
||||||
public String getSQL() {
|
this.columns = columns;
|
||||||
return Utils.toString(columns);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public abstract static class AbsColumn implements Selectable {
|
private static Column[] fromStrings(String... columnsString) {
|
||||||
|
final Column[] columns = new Column[columnsString.length];
|
||||||
|
for (int i = 0, j = columnsString.length; i < j; i++) {
|
||||||
|
columns[i] = new Column(columnsString[i]);
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return Utils.toString(columns, ',', true);
|
||||||
|
}
|
||||||
|
|
||||||
public static class AllColumn extends AbsColumn {
|
public abstract static class AbsColumn implements Selectable {
|
||||||
|
|
||||||
private final String table;
|
}
|
||||||
|
|
||||||
public AllColumn() {
|
public static class AllColumn extends AbsColumn {
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AllColumn(final String table) {
|
private final Table table;
|
||||||
this.table = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public AllColumn() {
|
||||||
public String getSQL() {
|
this(null);
|
||||||
return table != null ? table + ".*" : "*";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
public AllColumn(final Table table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Column extends AbsColumn {
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return table != null ? table.getSQL() + ".*" : "*";
|
||||||
|
}
|
||||||
|
|
||||||
private final String table, columnName, alias;
|
}
|
||||||
|
|
||||||
public Column(final String columnName) {
|
public static class Column extends AbsColumn {
|
||||||
this(null, columnName, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Column(final String columnName, final String alias) {
|
private final Table table;
|
||||||
this(null, columnName, alias);
|
private final String columnName, alias;
|
||||||
}
|
|
||||||
|
|
||||||
public Column(final String table, final String columnName, final String alias) {
|
public Column(final String columnName) {
|
||||||
if (columnName == null) throw new IllegalArgumentException("");
|
this(null, columnName, null);
|
||||||
this.table = table;
|
}
|
||||||
this.columnName = columnName;
|
|
||||||
this.alias = alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public Column(final String columnName, final String alias) {
|
||||||
public String getSQL() {
|
this(null, columnName, alias);
|
||||||
final String col = table != null ? table + "." + columnName : columnName;
|
}
|
||||||
return alias != null ? col + " AS " + alias : col;
|
|
||||||
}
|
public Column(final Table table, final String columnName) {
|
||||||
}
|
this(table, columnName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Column(final Table table, final String columnName, final String alias) {
|
||||||
|
if (columnName == null) throw new IllegalArgumentException("");
|
||||||
|
this.table = table;
|
||||||
|
this.columnName = columnName;
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
final String col = table != null ? table.getSQL() + "." + columnName : columnName;
|
||||||
|
return alias != null ? col + " AS " + alias : col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
*
|
||||||
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
* distribute this software, either in source code form or as a compiled
|
||||||
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
* means.
|
||||||
|
*
|
||||||
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
* of this software dedicate any and all copyright interest in the
|
||||||
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
* of the public at large and to the detriment of our heirs and
|
||||||
|
* successors. We intend this dedication to be an overt act of
|
||||||
|
* relinquishment in perpetuity of all present and future rights to this
|
||||||
|
* software under copyright law.
|
||||||
|
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class Expression implements SQLLang {
|
||||||
|
private final String expr;
|
||||||
|
|
||||||
|
public Expression(final String expr) {
|
||||||
|
this.expr = expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression(SQLLang lang) {
|
||||||
|
this(lang.getSQL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression and(final Expression... expressions) {
|
||||||
|
return new Expression(toExpr(expressions, "AND"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression equals(final Column l, final Column r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s = %s", l.getSQL(), r.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression equals(final Column l, final long r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s = %d", l.getSQL(), r));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression equals(final Column l, final String r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s = '%s'", l.getSQL(), r));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression equals(final String l, final long r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s = %d", l, r));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression in(final Column column, final Selectable in) {
|
||||||
|
return new Expression(String.format("%s IN(%s)", column.getSQL(), in.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression notEquals(final String l, final long r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s != %d", l, r));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression notEquals(final String l, final String r) {
|
||||||
|
return new Expression(String.format("%s != %s", l, r));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression notIn(final Column column, final Selectable in) {
|
||||||
|
return new Expression(String.format("%s NOT IN(%s)", column.getSQL(), in.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression notNull(final Column column) {
|
||||||
|
return new Expression(String.format("%s NOT NULL", column.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression or(final Expression... expressions) {
|
||||||
|
return new Expression(toExpr(expressions, "OR"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toExpr(final Expression[] array, final String token) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append('(');
|
||||||
|
final int length = array.length;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
builder.append(String.format(" %s ", token));
|
||||||
|
}
|
||||||
|
builder.append(array[i].getSQL());
|
||||||
|
}
|
||||||
|
builder.append(')');
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression equalsArgs(String l) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s = ?", l));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression isNull(Column column) {
|
||||||
|
return new Expression(String.format(Locale.ROOT, "%s IS NULL", column.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression greaterThan(Column column1, Column column2) {
|
||||||
|
return new Expression(String.format(Locale.ROOT, "%s > %s", column1.getSQL(), column2.getSQL()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression like(final Column l, final String r) {
|
||||||
|
return new Expression(String.format(Locale.US, "%s LIKE '%s'", l.getSQL(), r));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,36 +2,37 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class NewColumn implements SQLLang {
|
public class NewColumn implements SQLLang {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
public NewColumn(final String name, final String type) {
|
public NewColumn(final String name, final String type) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public static NewColumn[] createNewColumns(final String[] colNames, final String[] colTypes) {
|
||||||
return name;
|
if (colNames == null || colTypes == null || colNames.length != colTypes.length)
|
||||||
}
|
throw new IllegalArgumentException("length of columns and types not match.");
|
||||||
|
final NewColumn[] newColumns = new NewColumn[colNames.length];
|
||||||
|
for (int i = 0, j = colNames.length; i < j; i++) {
|
||||||
|
newColumns[i] = new NewColumn(colNames[i], colTypes[i]);
|
||||||
|
}
|
||||||
|
return newColumns;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public String getName() {
|
||||||
public String getSQL() {
|
return name;
|
||||||
if (name == null || type == null) throw new NullPointerException("name and type must not be null!");
|
}
|
||||||
return String.format("%s %s", name, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
@Override
|
||||||
return type;
|
public String getSQL() {
|
||||||
}
|
if (name == null || type == null)
|
||||||
|
throw new NullPointerException("name and type must not be null!");
|
||||||
|
return String.format("%s %s", name, type);
|
||||||
|
}
|
||||||
|
|
||||||
public static NewColumn[] createNewColumns(final String[] colNames, final String[] colTypes) {
|
public String getType() {
|
||||||
if (colNames == null || colTypes == null || colNames.length != colTypes.length)
|
return type;
|
||||||
throw new IllegalArgumentException("length of columns and types not match.");
|
}
|
||||||
final NewColumn[] newColumns = new NewColumn[colNames.length];
|
|
||||||
for (int i = 0, j = colNames.length; i < j; i++) {
|
|
||||||
newColumns[i] = new NewColumn(colNames[i], colTypes[i]);
|
|
||||||
}
|
|
||||||
return newColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 14-8-7.
|
||||||
|
*/
|
||||||
|
public enum OnConflict {
|
||||||
|
ROLLBACK("ROLLBACK"), ABORT("ABORT"), REPLACE("REPLACE"), FAIL("FAIL"), IGNORE("IGNORE");
|
||||||
|
private final String action;
|
||||||
|
|
||||||
|
OnConflict(final String action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,25 +21,26 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.querybuilder;
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.util.ArrayUtils;
|
import org.mariotaku.twidere.util.ArrayUtils;
|
||||||
|
|
||||||
public class OrderBy implements SQLLang {
|
public class OrderBy implements SQLLang {
|
||||||
|
|
||||||
private final String[] orderBy;
|
private final String[] orderBy;
|
||||||
|
|
||||||
public OrderBy(final String... orderBy) {
|
public OrderBy(final String... orderBy) {
|
||||||
this.orderBy = orderBy;
|
this.orderBy = orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
return ArrayUtils.toString(orderBy, ',', false);
|
return ArrayUtils.toString(orderBy, ',', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,23 +2,23 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class RawItemArray implements Selectable {
|
public class RawItemArray implements Selectable {
|
||||||
|
|
||||||
private final Object[] array;
|
private final Object[] array;
|
||||||
|
|
||||||
public RawItemArray(final long[] array) {
|
public RawItemArray(final long[] array) {
|
||||||
final Long[] converted = new Long[array.length];
|
final Long[] converted = new Long[array.length];
|
||||||
for (int i = 0, j = array.length; i < j; i++) {
|
for (int i = 0, j = array.length; i < j; i++) {
|
||||||
converted[i] = array[i];
|
converted[i] = array[i];
|
||||||
}
|
}
|
||||||
this.array = converted;
|
this.array = converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RawItemArray(final Object[] array) {
|
public RawItemArray(final String[] array) {
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
return Utils.toString(array, ',', false);
|
return Utils.toString(array, ',', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class SQLFunctions {
|
public class SQLFunctions {
|
||||||
|
|
||||||
public static String SUM(final String val) {
|
public static String SUM(final String val) {
|
||||||
return String.format("SUM (%s)", val);
|
return String.format("SUM (%s)", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String COUNT(final String val) {
|
||||||
|
return String.format("COUNT (%s)", val);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public interface SQLLang extends Cloneable {
|
public interface SQLLang extends Cloneable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build SQL query string
|
* Build SQL query string
|
||||||
*
|
*
|
||||||
* @return SQL query
|
* @return SQL query
|
||||||
*/
|
*/
|
||||||
public String getSQL();
|
public String getSQL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 14-8-6.
|
||||||
|
*/
|
||||||
|
public interface SQLQuery extends SQLLang {
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,70 +29,81 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.query.SQLAlterTableQuery;
|
import org.mariotaku.querybuilder.query.SQLAlterTableQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLCreateTableQuery;
|
import org.mariotaku.querybuilder.query.SQLCreateTableQuery;
|
||||||
|
import org.mariotaku.querybuilder.query.SQLCreateTriggerQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLCreateViewQuery;
|
import org.mariotaku.querybuilder.query.SQLCreateViewQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLDropTableQuery;
|
import org.mariotaku.querybuilder.query.SQLDropTableQuery;
|
||||||
|
import org.mariotaku.querybuilder.query.SQLDropTriggerQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLDropViewQuery;
|
import org.mariotaku.querybuilder.query.SQLDropViewQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLInsertIntoQuery;
|
import org.mariotaku.querybuilder.query.SQLInsertQuery;
|
||||||
import org.mariotaku.querybuilder.query.SQLInsertIntoQuery.OnConflict;
|
|
||||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||||
|
|
||||||
public class SQLQueryBuilder {
|
public class SQLQueryBuilder {
|
||||||
|
|
||||||
private SQLQueryBuilder() {
|
private SQLQueryBuilder() {
|
||||||
throw new AssertionError("You can't create instance for this class");
|
throw new AssertionError("You can't create instance for this class");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLAlterTableQuery.Builder alterTable(final String table) {
|
public static SQLAlterTableQuery.Builder alterTable(final String table) {
|
||||||
return new SQLAlterTableQuery.Builder().alterTable(table);
|
return new SQLAlterTableQuery.Builder().alterTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLCreateTableQuery.Builder createTable(final boolean temporary, final boolean createIfNotExists,
|
public static SQLCreateTableQuery.Builder createTable(final boolean temporary, final boolean createIfNotExists,
|
||||||
final String name) {
|
final String name) {
|
||||||
return new SQLCreateTableQuery.Builder().createTable(temporary, createIfNotExists, name);
|
return new SQLCreateTableQuery.Builder().createTable(temporary, createIfNotExists, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLCreateTableQuery.Builder createTable(final boolean createIfNotExists, final String name) {
|
public static SQLCreateTableQuery.Builder createTable(final boolean createIfNotExists, final String name) {
|
||||||
return createTable(false, createIfNotExists, name);
|
return createTable(false, createIfNotExists, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLCreateTableQuery.Builder createTable(final String name) {
|
public static SQLCreateTableQuery.Builder createTable(final String name) {
|
||||||
return createTable(false, false, name);
|
return createTable(false, false, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLCreateViewQuery.Builder createView(final boolean temporary, final boolean createIfNotExists,
|
public static SQLCreateViewQuery.Builder createView(final boolean temporary, final boolean createIfNotExists,
|
||||||
final String name) {
|
final String name) {
|
||||||
return new SQLCreateViewQuery.Builder().createView(temporary, createIfNotExists, name);
|
return new SQLCreateViewQuery.Builder().createView(temporary, createIfNotExists, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLCreateViewQuery.Builder createView(final boolean createIfNotExists, final String name) {
|
|
||||||
return createView(false, createIfNotExists, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SQLCreateViewQuery.Builder createView(final String name) {
|
public static SQLCreateTriggerQuery.Builder createTrigger(final boolean temporary, final boolean createIfNotExists,
|
||||||
return createView(false, false, name);
|
final String name) {
|
||||||
}
|
return new SQLCreateTriggerQuery.Builder().createTrigger(temporary, createIfNotExists, name);
|
||||||
|
}
|
||||||
|
|
||||||
public static SQLDropTableQuery dropTable(final boolean dropIfExists, final String table) {
|
public static SQLCreateViewQuery.Builder createView(final boolean createIfNotExists, final String name) {
|
||||||
return new SQLDropTableQuery(dropIfExists, table);
|
return createView(false, createIfNotExists, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLDropViewQuery dropView(final boolean dropIfExists, final String table) {
|
public static SQLCreateViewQuery.Builder createView(final String name) {
|
||||||
return new SQLDropViewQuery(dropIfExists, table);
|
return createView(false, false, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLInsertIntoQuery.Builder insertInto(final OnConflict onConflict, final String table) {
|
public static SQLDropTableQuery dropTable(final boolean dropIfExists, final String table) {
|
||||||
return new SQLInsertIntoQuery.Builder().insertInto(onConflict, table);
|
return new SQLDropTableQuery(dropIfExists, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLInsertIntoQuery.Builder insertInto(final String table) {
|
public static SQLDropViewQuery dropView(final boolean dropIfExists, final String table) {
|
||||||
return insertInto(null, table);
|
return new SQLDropViewQuery(dropIfExists, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLSelectQuery.Builder select(final boolean distinct, final Selectable select) {
|
public static SQLDropTriggerQuery dropTrigger(final boolean dropIfExists, final String table) {
|
||||||
return new SQLSelectQuery.Builder().select(distinct, select);
|
return new SQLDropTriggerQuery(dropIfExists, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SQLSelectQuery.Builder select(final Selectable select) {
|
public static SQLInsertQuery.Builder insertInto(final OnConflict onConflict, final String table) {
|
||||||
return select(false, select);
|
return new SQLInsertQuery.Builder().insertInto(onConflict, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SQLInsertQuery.Builder insertInto(final String table) {
|
||||||
|
return insertInto(null, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SQLSelectQuery.Builder select(final boolean distinct, final Selectable select) {
|
||||||
|
return new SQLSelectQuery.Builder().select(distinct, select);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SQLSelectQuery.Builder select(final Selectable select) {
|
||||||
|
return select(false, select);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,21 +29,21 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class SQLQueryException extends RuntimeException {
|
public class SQLQueryException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 910158450604676104L;
|
private static final long serialVersionUID = 910158450604676104L;
|
||||||
|
|
||||||
public SQLQueryException() {
|
public SQLQueryException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLQueryException(final String detailMessage) {
|
public SQLQueryException(final String detailMessage) {
|
||||||
super(detailMessage);
|
super(detailMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLQueryException(final String detailMessage, final Throwable throwable) {
|
public SQLQueryException(final String detailMessage, final Throwable throwable) {
|
||||||
super(detailMessage, throwable);
|
super(detailMessage, throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLQueryException(final Throwable throwable) {
|
public SQLQueryException(final Throwable throwable) {
|
||||||
super(throwable);
|
super(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 14-8-7.
|
||||||
|
*/
|
||||||
|
public class SetValue implements SQLLang {
|
||||||
|
|
||||||
|
private final Columns.Column column;
|
||||||
|
private final Expression expression;
|
||||||
|
|
||||||
|
public SetValue(Columns.Column column, Expression expression) {
|
||||||
|
this.column = column;
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return String.format(Locale.ROOT, "%s = %s", column.getSQL(), expression.getSQL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
*
|
||||||
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
* distribute this software, either in source code form or as a compiled
|
||||||
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
* means.
|
||||||
|
*
|
||||||
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
* of this software dedicate any and all copyright interest in the
|
||||||
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
* of the public at large and to the detriment of our heirs and
|
||||||
|
* successors. We intend this dedication to be an overt act of
|
||||||
|
* relinquishment in perpetuity of all present and future rights to this
|
||||||
|
* software under copyright law.
|
||||||
|
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
|
public class Table implements Selectable {
|
||||||
|
|
||||||
|
public static final Table NEW = new Table("NEW");
|
||||||
|
|
||||||
|
private final String table;
|
||||||
|
|
||||||
|
public Table(final String table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,23 +21,24 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.querybuilder;
|
package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class Tables implements Selectable {
|
public class Tables extends Table {
|
||||||
|
|
||||||
private final String[] tables;
|
private final String[] tables;
|
||||||
|
|
||||||
public Tables(final String... tables) {
|
public Tables(final String... tables) {
|
||||||
this.tables = tables;
|
super(null);
|
||||||
}
|
this.tables = tables;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
return Utils.toString(tables, ',', false);
|
return Utils.toString(tables, ',', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,34 +29,25 @@ package org.mariotaku.querybuilder;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
public static String toString(final Object[] array, final char token, final boolean include_space) {
|
public static String toString(final Object[] array, final char token, final boolean includeSpace) {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
final int length = array.length;
|
final int length = array.length;
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
final String id_string = String.valueOf(array[i]);
|
final String string = objectToString(array[i]);
|
||||||
if (id_string != null) {
|
if (string != null) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
builder.append(include_space ? token + " " : token);
|
builder.append(includeSpace ? token + " " : token);
|
||||||
}
|
}
|
||||||
builder.append(id_string);
|
builder.append(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toString(final SQLLang[] array) {
|
private static String objectToString(Object o) {
|
||||||
final StringBuilder builder = new StringBuilder();
|
if (o instanceof SQLLang)
|
||||||
final int length = array.length;
|
return ((SQLLang) o).getSQL();
|
||||||
for (int i = 0; i < length; i++) {
|
return o != null ? o.toString() : null;
|
||||||
final String id_string = array[i].getSQL();
|
}
|
||||||
if (id_string != null) {
|
|
||||||
if (i > 0) {
|
|
||||||
builder.append(", ");
|
|
||||||
}
|
|
||||||
builder.append(id_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
/**
|
|
||||||
* This is free and unencumbered software released into the public domain.
|
|
||||||
*
|
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
||||||
* distribute this software, either in source code form or as a compiled
|
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
* means.
|
|
||||||
*
|
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
|
||||||
* of this software dedicate any and all copyright interest in the
|
|
||||||
* software to the public domain. We make this dedication for the benefit
|
|
||||||
* of the public at large and to the detriment of our heirs and
|
|
||||||
* successors. We intend this dedication to be an overt act of
|
|
||||||
* relinquishment in perpetuity of all present and future rights to this
|
|
||||||
* software under copyright law.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.mariotaku.querybuilder;
|
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Where implements SQLLang {
|
|
||||||
private final String expr;
|
|
||||||
|
|
||||||
public Where(final String expr) {
|
|
||||||
this.expr = expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSQL() {
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where and(final Where... expressions) {
|
|
||||||
return new Where(toExpr(expressions, "AND"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where equals(final Column l, final Column r) {
|
|
||||||
return new Where(String.format(Locale.ROOT, "%s = %s", l.getSQL(), r.getSQL()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where equals(final Column l, final long r) {
|
|
||||||
return new Where(String.format(Locale.ROOT, "%s = %d", l.getSQL(), r));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where equals(final Column l, final String r) {
|
|
||||||
return new Where(String.format(Locale.ROOT, "%s = '%s'", l.getSQL(), r));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where equals(final String l, final long r) {
|
|
||||||
return new Where(String.format(Locale.ROOT, "%s = %d", l, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where in(final Column column, final Selectable in) {
|
|
||||||
return new Where(String.format("%s IN(%s)", column.getSQL(), in.getSQL()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where notEquals(final String l, final long r) {
|
|
||||||
return new Where(String.format(Locale.ROOT, "%s != %d", l, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where notEquals(final String l, final String r) {
|
|
||||||
return new Where(String.format("%s != %s", l, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where notIn(final Column column, final Selectable in) {
|
|
||||||
return new Where(String.format("%s NOT IN(%s)", column.getSQL(), in.getSQL()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where notNull(final Column column) {
|
|
||||||
return new Where(String.format("%s NOT NULL", column.getSQL()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Where or(final Where... expressions) {
|
|
||||||
return new Where(toExpr(expressions, "OR"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String toExpr(final Where[] array, final String token) {
|
|
||||||
final StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append('(');
|
|
||||||
final int length = array.length;
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
builder.append(String.format(" %s ", token));
|
|
||||||
}
|
|
||||||
builder.append(array[i].getSQL());
|
|
||||||
}
|
|
||||||
builder.append(')');
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,13 +4,13 @@ import org.mariotaku.querybuilder.SQLLang;
|
||||||
|
|
||||||
public interface IBuilder<T extends SQLLang> {
|
public interface IBuilder<T extends SQLLang> {
|
||||||
|
|
||||||
public T build();
|
public T build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to {@link #build()}.{@link #SQLLang.getSQL()}
|
* Equivalent to {@link #build()}.{@link SQLLang#getSQL()}
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String buildSQL();
|
public String buildSQL();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,71 +1,70 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.NewColumn;
|
import org.mariotaku.querybuilder.NewColumn;
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
|
||||||
public class SQLAlterTableQuery implements SQLLang {
|
public class SQLAlterTableQuery implements SQLQuery {
|
||||||
|
|
||||||
private String table;
|
private String table;
|
||||||
private String renameTo;
|
private String renameTo;
|
||||||
private NewColumn addColumn;
|
private NewColumn addColumn;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
if (table == null) throw new NullPointerException("table must not be null!");
|
if (table == null) throw new NullPointerException("table must not be null!");
|
||||||
if (renameTo == null && addColumn == null) throw new NullPointerException();
|
if (renameTo == null && addColumn == null) throw new NullPointerException();
|
||||||
if (renameTo != null) return String.format("ALTER TABLE %s RENAME TO %s", table, renameTo);
|
if (renameTo != null) return String.format("ALTER TABLE %s RENAME TO %s", table, renameTo);
|
||||||
return String.format("ALTER TABLE %s ADD COLUMN %s", table, addColumn.getSQL());
|
return String.format("ALTER TABLE %s ADD COLUMN %s", table, addColumn.getSQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAddColumn(final NewColumn addColumn) {
|
void setAddColumn(final NewColumn addColumn) {
|
||||||
this.addColumn = addColumn;
|
this.addColumn = addColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRenameTo(final String renameTo) {
|
void setRenameTo(final String renameTo) {
|
||||||
this.renameTo = renameTo;
|
this.renameTo = renameTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTable(final String table) {
|
void setTable(final String table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLAlterTableQuery> {
|
public static final class Builder implements IBuilder<SQLAlterTableQuery> {
|
||||||
|
|
||||||
private boolean buildCalled;
|
private final SQLAlterTableQuery query = new SQLAlterTableQuery();
|
||||||
|
private boolean buildCalled;
|
||||||
|
|
||||||
private final SQLAlterTableQuery query = new SQLAlterTableQuery();
|
public Builder addColumn(final NewColumn addColumn) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setAddColumn(addColumn);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder addColumn(final NewColumn addColumn) {
|
public Builder alterTable(final String table) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setAddColumn(addColumn);
|
query.setTable(table);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder alterTable(final String table) {
|
@Override
|
||||||
checkNotBuilt();
|
public SQLAlterTableQuery build() {
|
||||||
query.setTable(table);
|
return query;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLAlterTableQuery build() {
|
public String buildSQL() {
|
||||||
return query;
|
return build().getSQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Builder renameTo(final String renameTo) {
|
||||||
public String buildSQL() {
|
checkNotBuilt();
|
||||||
return build().getSQL();
|
query.setRenameTo(renameTo);
|
||||||
}
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder renameTo(final String renameTo) {
|
private void checkNotBuilt() {
|
||||||
checkNotBuilt();
|
if (buildCalled) throw new IllegalStateException();
|
||||||
query.setRenameTo(renameTo);
|
}
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void checkNotBuilt() {
|
|
||||||
if (buildCalled) throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,111 +1,111 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.NewColumn;
|
import org.mariotaku.querybuilder.NewColumn;
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
import org.mariotaku.querybuilder.Utils;
|
import org.mariotaku.querybuilder.Utils;
|
||||||
|
|
||||||
public class SQLCreateTableQuery implements SQLLang {
|
public class SQLCreateTableQuery implements SQLQuery {
|
||||||
|
|
||||||
private boolean temporary;
|
private boolean temporary;
|
||||||
private boolean createIfNotExists;
|
private boolean createIfNotExists;
|
||||||
private String table;
|
private String table;
|
||||||
private NewColumn[] newColumns;
|
private NewColumn[] newColumns;
|
||||||
private SQLSelectQuery selectStmt;
|
private SQLSelectQuery selectStmt;
|
||||||
|
|
||||||
SQLCreateTableQuery() {
|
SQLCreateTableQuery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
if (table == null) throw new NullPointerException("NAME must not be null!");
|
if (table == null) throw new NullPointerException("NAME must not be null!");
|
||||||
if ((newColumns == null || newColumns.length == 0) && selectStmt == null)
|
if ((newColumns == null || newColumns.length == 0) && selectStmt == null)
|
||||||
throw new NullPointerException("Columns or AS must not be null!");
|
throw new NullPointerException("Columns or AS must not be null!");
|
||||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||||
if (temporary) {
|
if (temporary) {
|
||||||
sb.append("TEMPORARY ");
|
sb.append("TEMPORARY ");
|
||||||
}
|
}
|
||||||
sb.append("TABLE ");
|
sb.append("TABLE ");
|
||||||
if (createIfNotExists) {
|
if (createIfNotExists) {
|
||||||
sb.append("IF NOT EXISTS ");
|
sb.append("IF NOT EXISTS ");
|
||||||
}
|
}
|
||||||
sb.append(String.format("%s ", table));
|
sb.append(String.format("%s ", table));
|
||||||
if (newColumns != null && newColumns.length > 0) {
|
if (newColumns != null && newColumns.length > 0) {
|
||||||
sb.append(String.format("(%s)", Utils.toString(newColumns)));
|
sb.append(String.format("(%s)", Utils.toString(newColumns, ',', true)));
|
||||||
} else {
|
} else {
|
||||||
sb.append(String.format("AS %s", selectStmt.getSQL()));
|
sb.append(String.format("AS %s", selectStmt.getSQL()));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAs(final SQLSelectQuery selectStmt) {
|
void setAs(final SQLSelectQuery selectStmt) {
|
||||||
this.selectStmt = selectStmt;
|
this.selectStmt = selectStmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||||
this.createIfNotExists = createIfNotExists;
|
this.createIfNotExists = createIfNotExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNewColumns(final NewColumn[] newColumns) {
|
void setNewColumns(final NewColumn[] newColumns) {
|
||||||
this.newColumns = newColumns;
|
this.newColumns = newColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTable(final String table) {
|
void setTable(final String table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTemporary(final boolean temporary) {
|
void setTemporary(final boolean temporary) {
|
||||||
this.temporary = temporary;
|
this.temporary = temporary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLCreateTableQuery> {
|
public static final class Builder implements IBuilder<SQLCreateTableQuery> {
|
||||||
|
|
||||||
private final SQLCreateTableQuery query = new SQLCreateTableQuery();
|
private final SQLCreateTableQuery query = new SQLCreateTableQuery();
|
||||||
|
|
||||||
private boolean buildCalled;
|
private boolean buildCalled;
|
||||||
|
|
||||||
public Builder as(final SQLSelectQuery selectStmt) {
|
public Builder as(final SQLSelectQuery selectStmt) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setAs(selectStmt);
|
query.setAs(selectStmt);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLCreateTableQuery build() {
|
public SQLCreateTableQuery build() {
|
||||||
buildCalled = true;
|
buildCalled = true;
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildSQL() {
|
public String buildSQL() {
|
||||||
return build().getSQL();
|
return build().getSQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder columns(final NewColumn... newColumns) {
|
public Builder columns(final NewColumn... newColumns) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setNewColumns(newColumns);
|
query.setNewColumns(newColumns);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder createTable(final boolean temporary, final boolean createIfNotExists, final String table) {
|
public Builder createTable(final boolean temporary, final boolean createIfNotExists, final String table) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setTemporary(temporary);
|
query.setTemporary(temporary);
|
||||||
query.setCreateIfNotExists(createIfNotExists);
|
query.setCreateIfNotExists(createIfNotExists);
|
||||||
query.setTable(table);
|
query.setTable(table);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder createTable(final boolean createIfNotExists, final String table) {
|
public Builder createTable(final boolean createIfNotExists, final String table) {
|
||||||
return createTable(false, createIfNotExists, table);
|
return createTable(false, createIfNotExists, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder createTemporaryTable(final boolean createIfNotExists, final String table) {
|
public Builder createTemporaryTable(final boolean createIfNotExists, final String table) {
|
||||||
return createTable(true, createIfNotExists, table);
|
return createTable(true, createIfNotExists, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNotBuilt() {
|
private void checkNotBuilt() {
|
||||||
if (buildCalled) throw new IllegalStateException();
|
if (buildCalled) throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.Columns;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
|
import org.mariotaku.querybuilder.SQLLang;
|
||||||
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
import org.mariotaku.querybuilder.Table;
|
||||||
|
import org.mariotaku.querybuilder.Utils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 14-8-6.
|
||||||
|
*/
|
||||||
|
public class SQLCreateTriggerQuery implements SQLQuery {
|
||||||
|
|
||||||
|
private boolean temporary;
|
||||||
|
private boolean createIfNotExists;
|
||||||
|
private boolean forEachRow;
|
||||||
|
private String name;
|
||||||
|
private Table on;
|
||||||
|
private Type type;
|
||||||
|
private Event event;
|
||||||
|
private Columns updateOf;
|
||||||
|
private SQLQuery[] actions;
|
||||||
|
private Expression when;
|
||||||
|
|
||||||
|
void setActions(SQLQuery[] actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setForEachRow(boolean forEachRow) {
|
||||||
|
this.forEachRow = forEachRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOn(Table on) {
|
||||||
|
this.on = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpdateOf(Columns updateOf) {
|
||||||
|
this.updateOf = updateOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEvent(Event event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWhen(Expression when) {
|
||||||
|
this.when = when;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
if (name == null) throw new NullPointerException("NAME must not be null!");
|
||||||
|
if (event == null) throw new NullPointerException("EVENT must not be null!");
|
||||||
|
if (on == null) throw new NullPointerException("ON must not be null!");
|
||||||
|
if (actions == null) throw new NullPointerException("ACTIONS must not be null!");
|
||||||
|
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||||
|
if (temporary) {
|
||||||
|
sb.append("TEMPORARY ");
|
||||||
|
}
|
||||||
|
sb.append("TRIGGER ");
|
||||||
|
if (createIfNotExists) {
|
||||||
|
sb.append("IF NOT EXISTS ");
|
||||||
|
}
|
||||||
|
sb.append(name);
|
||||||
|
sb.append(' ');
|
||||||
|
if (type != null) {
|
||||||
|
sb.append(type.getSQL());
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
sb.append(event.getSQL());
|
||||||
|
sb.append(' ');
|
||||||
|
if (event == Event.UPDATE) {
|
||||||
|
sb.append(String.format(Locale.ROOT, "%s ", updateOf.getSQL()));
|
||||||
|
}
|
||||||
|
sb.append(String.format(Locale.ROOT, "ON %s ", on.getSQL()));
|
||||||
|
if (forEachRow) {
|
||||||
|
sb.append("FOR EACH ROW ");
|
||||||
|
}
|
||||||
|
if (when != null) {
|
||||||
|
sb.append(String.format(Locale.ROOT, "WHEN %s ", when.getSQL()));
|
||||||
|
}
|
||||||
|
sb.append(String.format(Locale.ROOT, "BEGIN %s; END", Utils.toString(actions, ';', true)));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||||
|
this.createIfNotExists = createIfNotExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTemporary(final boolean temporary) {
|
||||||
|
this.temporary = temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Type implements SQLLang {
|
||||||
|
BEFORE("BEFORE"), AFTER("AFTER"), INSTEAD_OF("INSTEAD OF");
|
||||||
|
private final String lang;
|
||||||
|
|
||||||
|
Type(String lang) {
|
||||||
|
this.lang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Event implements SQLLang {
|
||||||
|
INSERT("INSERT"), DELETE("DELETE"), UPDATE("UPDATE");
|
||||||
|
private final String lang;
|
||||||
|
|
||||||
|
Event(String lang) {
|
||||||
|
this.lang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder implements IBuilder<SQLCreateTriggerQuery> {
|
||||||
|
|
||||||
|
private final SQLCreateTriggerQuery query = new SQLCreateTriggerQuery();
|
||||||
|
private boolean buildCalled;
|
||||||
|
|
||||||
|
public Builder forEachRow(final boolean forEachRow) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setForEachRow(forEachRow);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder on(final Table on) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setOn(on);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder event(Event event) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setEvent(event);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder type(Type type) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setType(type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder updateOf(Columns updateOf) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setUpdateOf(updateOf);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder actions(SQLQuery... actions) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setActions(actions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder when(Expression when) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setWhen(when);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLCreateTriggerQuery build() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildSQL() {
|
||||||
|
return build().getSQL();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNotBuilt() {
|
||||||
|
if (buildCalled) throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder createTrigger(boolean temporary, boolean createIfNotExists, String name) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setTemporary(temporary);
|
||||||
|
query.setCreateIfNotExists(createIfNotExists);
|
||||||
|
query.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,90 +1,90 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
|
||||||
public class SQLCreateViewQuery implements SQLLang {
|
public class SQLCreateViewQuery implements SQLQuery {
|
||||||
|
|
||||||
private boolean temporary;
|
private boolean temporary;
|
||||||
private boolean createIfNotExists;
|
private boolean createIfNotExists;
|
||||||
private String name;
|
private String name;
|
||||||
private SQLSelectQuery selectStmt;
|
private SQLSelectQuery selectStmt;
|
||||||
|
|
||||||
SQLCreateViewQuery() {
|
SQLCreateViewQuery() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
if (name == null) throw new NullPointerException("NAME must not be null!");
|
if (name == null) throw new NullPointerException("NAME must not be null!");
|
||||||
if (selectStmt == null) throw new NullPointerException("SELECT statement must not be null!");
|
if (selectStmt == null)
|
||||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
throw new NullPointerException("SELECT statement must not be null!");
|
||||||
if (temporary) {
|
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||||
sb.append("TEMPORARY ");
|
if (temporary) {
|
||||||
}
|
sb.append("TEMPORARY ");
|
||||||
sb.append("VIEW ");
|
}
|
||||||
if (createIfNotExists) {
|
sb.append("VIEW ");
|
||||||
sb.append("IF NOT EXISTS ");
|
if (createIfNotExists) {
|
||||||
}
|
sb.append("IF NOT EXISTS ");
|
||||||
sb.append(String.format("%s AS %s", name, selectStmt.getSQL()));
|
}
|
||||||
return sb.toString();
|
sb.append(String.format("%s AS %s", name, selectStmt.getSQL()));
|
||||||
}
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
void setAs(final SQLSelectQuery selectStmt) {
|
void setAs(final SQLSelectQuery selectStmt) {
|
||||||
this.selectStmt = selectStmt;
|
this.selectStmt = selectStmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||||
this.createIfNotExists = createIfNotExists;
|
this.createIfNotExists = createIfNotExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setName(final String name) {
|
void setName(final String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTemporary(final boolean temporary) {
|
void setTemporary(final boolean temporary) {
|
||||||
this.temporary = temporary;
|
this.temporary = temporary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLCreateViewQuery> {
|
public static final class Builder implements IBuilder<SQLCreateViewQuery> {
|
||||||
|
|
||||||
private boolean buildCalled;
|
private final SQLCreateViewQuery query = new SQLCreateViewQuery();
|
||||||
|
private boolean buildCalled;
|
||||||
|
|
||||||
private final SQLCreateViewQuery query = new SQLCreateViewQuery();
|
public Builder as(final SQLSelectQuery selectStmt) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setAs(selectStmt);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder as(final SQLSelectQuery selectStmt) {
|
@Override
|
||||||
checkNotBuilt();
|
public SQLCreateViewQuery build() {
|
||||||
query.setAs(selectStmt);
|
return query;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLCreateViewQuery build() {
|
public String buildSQL() {
|
||||||
return query;
|
return build().getSQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Builder createTemporaryView(final boolean createIfNotExists, final String name) {
|
||||||
public String buildSQL() {
|
return createView(true, createIfNotExists, name);
|
||||||
return build().getSQL();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Builder createTemporaryView(final boolean createIfNotExists, final String name) {
|
public Builder createView(final boolean temporary, final boolean createIfNotExists, final String name) {
|
||||||
return createView(true, createIfNotExists, name);
|
checkNotBuilt();
|
||||||
}
|
query.setTemporary(temporary);
|
||||||
|
query.setCreateIfNotExists(createIfNotExists);
|
||||||
|
query.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder createView(final boolean temporary, final boolean createIfNotExists, final String name) {
|
public Builder createView(final boolean createIfNotExists, final String name) {
|
||||||
checkNotBuilt();
|
return createView(false, createIfNotExists, name);
|
||||||
query.setTemporary(temporary);
|
}
|
||||||
query.setCreateIfNotExists(createIfNotExists);
|
|
||||||
query.setName(name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder createView(final boolean createIfNotExists, final String name) {
|
private void checkNotBuilt() {
|
||||||
return createView(false, createIfNotExists, name);
|
if (buildCalled) throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void checkNotBuilt() {
|
|
||||||
if (buildCalled) throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.Where;
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
|
||||||
public class SQLDeleteQuery implements SQLLang {
|
public class SQLDeleteQuery implements SQLQuery {
|
||||||
|
|
||||||
private String table;
|
private String table;
|
||||||
private Where where;
|
private Expression where;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
if (where != null) return String.format("DELETE FROM %s", table);
|
if (where != null) return String.format("DELETE FROM %s", table);
|
||||||
return String.format("DELETE FROM %S WHERE %s", table, where.getSQL());
|
return String.format("DELETE FROM %S WHERE %s", table, where.getSQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFrom(final String table) {
|
void setFrom(final String table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWhere(final Where where) {
|
void setWhere(final Expression where) {
|
||||||
this.where = where;
|
this.where = where;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLDeleteQuery> {
|
public static final class Builder implements IBuilder<SQLDeleteQuery> {
|
||||||
private boolean buildCalled;
|
private final SQLDeleteQuery query = new SQLDeleteQuery();
|
||||||
private final SQLDeleteQuery query = new SQLDeleteQuery();
|
private boolean buildCalled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLDeleteQuery build() {
|
public SQLDeleteQuery build() {
|
||||||
buildCalled = true;
|
buildCalled = true;
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildSQL() {
|
public String buildSQL() {
|
||||||
return build().getSQL();
|
return build().getSQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder from(final String table) {
|
public Builder from(final String table) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setFrom(table);
|
query.setFrom(table);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder where(final Where where) {
|
public Builder where(final Expression where) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setWhere(where);
|
query.setWhere(where);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNotBuilt() {
|
private void checkNotBuilt() {
|
||||||
if (buildCalled) throw new IllegalStateException();
|
if (buildCalled) throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
|
||||||
public class SQLDropQuery implements SQLLang {
|
public class SQLDropQuery implements SQLQuery {
|
||||||
|
|
||||||
private final String table;
|
private final boolean dropIfExists;
|
||||||
|
private final String type;
|
||||||
|
private final String target;
|
||||||
|
|
||||||
public SQLDropQuery(final String table) {
|
public SQLDropQuery(final boolean dropIfExists, final String type, final String target) {
|
||||||
if (table == null) throw new NullPointerException();
|
if (target == null) throw new NullPointerException();
|
||||||
this.table = table;
|
this.dropIfExists = dropIfExists;
|
||||||
}
|
this.type = type;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public final String getSQL() {
|
||||||
return String.format("DROP TABLE %s", table);
|
if (dropIfExists) return String.format("DROP %s IF EXISTS %s", type, target);
|
||||||
}
|
return String.format("DROP %s %s", type, target);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
public class SQLDropTableQuery extends SQLDropQuery {
|
||||||
|
|
||||||
public class SQLDropTableQuery implements SQLLang {
|
public SQLDropTableQuery(final boolean dropIfExists, final String table) {
|
||||||
|
super(dropIfExists, "TABLE", table);
|
||||||
private final boolean dropIfExists;
|
}
|
||||||
private final String table;
|
|
||||||
|
|
||||||
public SQLDropTableQuery(final boolean dropIfExists, final String table) {
|
|
||||||
if (table == null) throw new NullPointerException();
|
|
||||||
this.dropIfExists = dropIfExists;
|
|
||||||
this.table = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSQL() {
|
|
||||||
if (dropIfExists) return String.format("DROP TABLE IF EXISTS %s", table);
|
|
||||||
return String.format("DROP TABLE %s", table);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
|
public class SQLDropTriggerQuery extends SQLDropQuery {
|
||||||
|
|
||||||
|
public SQLDropTriggerQuery(final boolean dropIfExists, final String table) {
|
||||||
|
super(dropIfExists, "TRIGGER", table);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,22 +1,9 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
public class SQLDropViewQuery extends SQLDropQuery {
|
||||||
|
|
||||||
public class SQLDropViewQuery implements SQLLang {
|
public SQLDropViewQuery(final boolean dropIfExists, final String table) {
|
||||||
|
super(dropIfExists, "VIEW", table);
|
||||||
private final boolean dropIfExists;
|
}
|
||||||
private final String table;
|
|
||||||
|
|
||||||
public SQLDropViewQuery(final boolean dropIfExists, final String table) {
|
|
||||||
if (table == null) throw new NullPointerException();
|
|
||||||
this.dropIfExists = dropIfExists;
|
|
||||||
this.table = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSQL() {
|
|
||||||
if (dropIfExists) return String.format("DROP VIEW IF EXISTS %s", table);
|
|
||||||
return String.format("DROP VIEW %s", table);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
package org.mariotaku.querybuilder.query;
|
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
|
||||||
import org.mariotaku.querybuilder.Utils;
|
|
||||||
|
|
||||||
public class SQLInsertIntoQuery implements SQLLang {
|
|
||||||
|
|
||||||
private OnConflict onConflict;
|
|
||||||
private String table;
|
|
||||||
private String[] columns;
|
|
||||||
private SQLSelectQuery select;
|
|
||||||
|
|
||||||
SQLInsertIntoQuery() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSQL() {
|
|
||||||
if (table == null) throw new NullPointerException("table must not be null!");
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("INSERT ");
|
|
||||||
if (onConflict != null) {
|
|
||||||
sb.append(String.format("OR %s ", onConflict.getAction()));
|
|
||||||
}
|
|
||||||
sb.append(String.format("INTO %s ", table));
|
|
||||||
sb.append(String.format("(%s) ", Utils.toString(columns, ',', false)));
|
|
||||||
sb.append(String.format("%s ", select.getSQL()));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setColumns(final String[] columns) {
|
|
||||||
this.columns = columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOnConflict(final OnConflict onConflict) {
|
|
||||||
this.onConflict = onConflict;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSelect(final SQLSelectQuery select) {
|
|
||||||
this.select = select;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTable(final String table) {
|
|
||||||
this.table = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLInsertIntoQuery> {
|
|
||||||
|
|
||||||
private final SQLInsertIntoQuery query = new SQLInsertIntoQuery();
|
|
||||||
|
|
||||||
private boolean buildCalled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLInsertIntoQuery build() {
|
|
||||||
buildCalled = true;
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String buildSQL() {
|
|
||||||
return build().getSQL();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder columns(final String[] columns) {
|
|
||||||
checkNotBuilt();
|
|
||||||
query.setColumns(columns);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder insertInto(final OnConflict onConflict, final String table) {
|
|
||||||
checkNotBuilt();
|
|
||||||
query.setOnConflict(onConflict);
|
|
||||||
query.setTable(table);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder insertInto(final String table) {
|
|
||||||
return insertInto(null, table);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder select(final SQLSelectQuery select) {
|
|
||||||
checkNotBuilt();
|
|
||||||
query.setSelect(select);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkNotBuilt() {
|
|
||||||
if (buildCalled) throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum OnConflict {
|
|
||||||
ROLLBACK("ROLLBACK"), ABORT("ABORT"), REPLACE("REPLACE"), FAIL("FAIL"), IGNORE("IGNORE");
|
|
||||||
private final String action;
|
|
||||||
|
|
||||||
private OnConflict(final String action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.OnConflict;
|
||||||
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
import org.mariotaku.querybuilder.Utils;
|
||||||
|
|
||||||
|
public class SQLInsertQuery implements SQLQuery {
|
||||||
|
|
||||||
|
private OnConflict onConflict;
|
||||||
|
private String table;
|
||||||
|
private String[] columns;
|
||||||
|
private SQLSelectQuery select;
|
||||||
|
|
||||||
|
SQLInsertQuery() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
if (table == null) throw new NullPointerException("table must not be null!");
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("INSERT ");
|
||||||
|
if (onConflict != null) {
|
||||||
|
sb.append(String.format("OR %s ", onConflict.getAction()));
|
||||||
|
}
|
||||||
|
sb.append(String.format("INTO %s ", table));
|
||||||
|
sb.append(String.format("(%s) ", Utils.toString(columns, ',', false)));
|
||||||
|
sb.append(String.format("%s ", select.getSQL()));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setColumns(final String[] columns) {
|
||||||
|
this.columns = columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnConflict(final OnConflict onConflict) {
|
||||||
|
this.onConflict = onConflict;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSelect(final SQLSelectQuery select) {
|
||||||
|
this.select = select;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTable(final String table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder implements IBuilder<SQLInsertQuery> {
|
||||||
|
|
||||||
|
private final SQLInsertQuery query = new SQLInsertQuery();
|
||||||
|
|
||||||
|
private boolean buildCalled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLInsertQuery build() {
|
||||||
|
buildCalled = true;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildSQL() {
|
||||||
|
return build().getSQL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder columns(final String[] columns) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setColumns(columns);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder insertInto(final OnConflict onConflict, final String table) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setOnConflict(onConflict);
|
||||||
|
query.setTable(table);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder insertInto(final String table) {
|
||||||
|
return insertInto(null, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder select(final SQLSelectQuery select) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setSelect(select);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNotBuilt() {
|
||||||
|
if (buildCalled) throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* This is free and unencumbered software released into the public domain.
|
* This is free and unencumbered software released into the public domain.
|
||||||
*
|
*
|
||||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
* distribute this software, either in source code form or as a compiled
|
* distribute this software, either in source code form or as a compiled
|
||||||
* binary, for any purpose, commercial or non-commercial, and by any
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
* means.
|
* means.
|
||||||
*
|
*
|
||||||
* In jurisdictions that recognize copyright laws, the author or authors
|
* In jurisdictions that recognize copyright laws, the author or authors
|
||||||
* of this software dedicate any and all copyright interest in the
|
* of this software dedicate any and all copyright interest in the
|
||||||
* software to the public domain. We make this dedication for the benefit
|
* software to the public domain. We make this dedication for the benefit
|
||||||
|
@ -21,240 +21,241 @@
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* For more information, please refer to <http://unlicense.org/>
|
* For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.querybuilder.query;
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.OrderBy;
|
import org.mariotaku.querybuilder.OrderBy;
|
||||||
import org.mariotaku.querybuilder.SQLLang;
|
import org.mariotaku.querybuilder.SQLLang;
|
||||||
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
import org.mariotaku.querybuilder.SQLQueryException;
|
import org.mariotaku.querybuilder.SQLQueryException;
|
||||||
import org.mariotaku.querybuilder.Selectable;
|
import org.mariotaku.querybuilder.Selectable;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SQLSelectQuery implements Selectable {
|
public class SQLSelectQuery implements SQLQuery, Selectable {
|
||||||
|
|
||||||
private final List<InternalQuery> internalQueries = new ArrayList<InternalQuery>();
|
private final List<InternalQuery> internalQueries = new ArrayList<InternalQuery>();
|
||||||
|
|
||||||
private InternalQuery currentInternalQuery;
|
private InternalQuery currentInternalQuery;
|
||||||
private OrderBy orderBy;
|
private OrderBy orderBy;
|
||||||
private Integer limit = null, offset = null;
|
private Integer limit = null, offset = null;
|
||||||
|
|
||||||
SQLSelectQuery() {
|
SQLSelectQuery() {
|
||||||
initCurrentQuery();
|
initCurrentQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
final int size = internalQueries.size();
|
final int size = internalQueries.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
sb.append("UNION ");
|
sb.append("UNION ");
|
||||||
}
|
}
|
||||||
final InternalQuery query = internalQueries.get(i);
|
final InternalQuery query = internalQueries.get(i);
|
||||||
sb.append(query.getSQL());
|
sb.append(query.getSQL());
|
||||||
|
|
||||||
}
|
}
|
||||||
if (orderBy != null) {
|
if (orderBy != null) {
|
||||||
sb.append(String.format("ORDER BY %s ", orderBy.getSQL()));
|
sb.append(String.format("ORDER BY %s ", orderBy.getSQL()));
|
||||||
}
|
}
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
sb.append(String.format("LIMIT %s ", limit));
|
sb.append(String.format("LIMIT %s ", limit));
|
||||||
if (offset != null) {
|
if (offset != null) {
|
||||||
sb.append(String.format("OFFSET %s ", offset));
|
sb.append(String.format("OFFSET %s ", offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initCurrentQuery() {
|
private void initCurrentQuery() {
|
||||||
currentInternalQuery = new InternalQuery();
|
currentInternalQuery = new InternalQuery();
|
||||||
internalQueries.add(currentInternalQuery);
|
internalQueries.add(currentInternalQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDistinct(final boolean distinct) {
|
void setDistinct(final boolean distinct) {
|
||||||
currentInternalQuery.setDistinct(distinct);
|
currentInternalQuery.setDistinct(distinct);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFrom(final Selectable from) {
|
void setFrom(final Selectable from) {
|
||||||
currentInternalQuery.setFrom(from);
|
currentInternalQuery.setFrom(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGroupBy(final Selectable groupBy) {
|
void setGroupBy(final Selectable groupBy) {
|
||||||
currentInternalQuery.setGroupBy(groupBy);
|
currentInternalQuery.setGroupBy(groupBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHaving(final Where having) {
|
void setHaving(final Expression having) {
|
||||||
currentInternalQuery.setHaving(having);
|
currentInternalQuery.setHaving(having);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLimit(final int limit) {
|
void setLimit(final int limit) {
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOffset(final int offset) {
|
void setOffset(final int offset) {
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOrderBy(final OrderBy orderBy) {
|
void setOrderBy(final OrderBy orderBy) {
|
||||||
this.orderBy = orderBy;
|
this.orderBy = orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelect(final Selectable select) {
|
void setSelect(final Selectable select) {
|
||||||
currentInternalQuery.setSelect(select);
|
currentInternalQuery.setSelect(select);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWhere(final Where where) {
|
void setWhere(final Expression where) {
|
||||||
currentInternalQuery.setWhere(where);
|
currentInternalQuery.setWhere(where);
|
||||||
}
|
}
|
||||||
|
|
||||||
void union() {
|
void union() {
|
||||||
initCurrentQuery();
|
initCurrentQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder implements IBuilder<SQLSelectQuery> {
|
public static final class Builder implements IBuilder<SQLSelectQuery> {
|
||||||
private boolean buildCalled;
|
private final SQLSelectQuery query = new SQLSelectQuery();
|
||||||
private final SQLSelectQuery query = new SQLSelectQuery();
|
private boolean buildCalled;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLSelectQuery build() {
|
public SQLSelectQuery build() {
|
||||||
buildCalled = true;
|
buildCalled = true;
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildSQL() {
|
public String buildSQL() {
|
||||||
return build().getSQL();
|
return build().getSQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder from(final Selectable from) {
|
public Builder from(final Selectable from) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setFrom(from);
|
query.setFrom(from);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder groupBy(final Selectable groupBy) {
|
public Builder groupBy(final Selectable groupBy) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setGroupBy(groupBy);
|
query.setGroupBy(groupBy);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder having(final Where having) {
|
public Builder having(final Expression having) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setHaving(having);
|
query.setHaving(having);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder limit(final int limit) {
|
public Builder limit(final int limit) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setLimit(limit);
|
query.setLimit(limit);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder offset(final int offset) {
|
public Builder offset(final int offset) {
|
||||||
query.setOffset(offset);
|
query.setOffset(offset);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder orderBy(final OrderBy orderBy) {
|
public Builder orderBy(final OrderBy orderBy) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setOrderBy(orderBy);
|
query.setOrderBy(orderBy);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder select(final boolean distinct, final Selectable select) {
|
public Builder select(final boolean distinct, final Selectable select) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setSelect(select);
|
query.setSelect(select);
|
||||||
query.setDistinct(distinct);
|
query.setDistinct(distinct);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder select(final Selectable select) {
|
public Builder select(final Selectable select) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
select(false, select);
|
select(false, select);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder union() {
|
public Builder union() {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.union();
|
query.union();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder where(final Where where) {
|
public Builder where(final Expression where) {
|
||||||
checkNotBuilt();
|
checkNotBuilt();
|
||||||
query.setWhere(where);
|
query.setWhere(where);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNotBuilt() {
|
private void checkNotBuilt() {
|
||||||
if (buildCalled) throw new IllegalStateException();
|
if (buildCalled) throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InternalQuery implements SQLLang {
|
private static class InternalQuery implements SQLLang {
|
||||||
|
|
||||||
private boolean distinct;
|
private boolean distinct;
|
||||||
private Selectable select, from, groupBy;
|
private Selectable select, from, groupBy;
|
||||||
private Where where, having;
|
private Expression where, having;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
if (select == null) throw new SQLQueryException("selectable is null");
|
if (select == null) throw new SQLQueryException("selectable is null");
|
||||||
final StringBuilder sb = new StringBuilder("SELECT ");
|
final StringBuilder sb = new StringBuilder("SELECT ");
|
||||||
if (distinct) {
|
if (distinct) {
|
||||||
sb.append("DISTINCT ");
|
sb.append("DISTINCT ");
|
||||||
}
|
}
|
||||||
sb.append(String.format("%s ", select.getSQL()));
|
sb.append(String.format("%s ", select.getSQL()));
|
||||||
if (!(select instanceof SQLSelectQuery) && from == null)
|
if (!(select instanceof SQLSelectQuery) && from == null)
|
||||||
throw new SQLQueryException("FROM not specified");
|
throw new SQLQueryException("FROM not specified");
|
||||||
else if (from != null) {
|
else if (from != null) {
|
||||||
if (from instanceof SQLSelectQuery) {
|
if (from instanceof SQLSelectQuery) {
|
||||||
sb.append(String.format("FROM (%s) ", from.getSQL()));
|
sb.append(String.format("FROM (%s) ", from.getSQL()));
|
||||||
} else {
|
} else {
|
||||||
sb.append(String.format("FROM %s ", from.getSQL()));
|
sb.append(String.format("FROM %s ", from.getSQL()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (where != null) {
|
if (where != null) {
|
||||||
sb.append(String.format("WHERE %s ", where.getSQL()));
|
sb.append(String.format("WHERE %s ", where.getSQL()));
|
||||||
}
|
}
|
||||||
if (groupBy != null) {
|
if (groupBy != null) {
|
||||||
sb.append(String.format("GROUP BY %s ", groupBy.getSQL()));
|
sb.append(String.format("GROUP BY %s ", groupBy.getSQL()));
|
||||||
if (having != null) {
|
if (having != null) {
|
||||||
sb.append(String.format("HAVING %s ", having.getSQL()));
|
sb.append(String.format("HAVING %s ", having.getSQL()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDistinct(final boolean distinct) {
|
void setDistinct(final boolean distinct) {
|
||||||
this.distinct = distinct;
|
this.distinct = distinct;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFrom(final Selectable from) {
|
void setFrom(final Selectable from) {
|
||||||
this.from = from;
|
this.from = from;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGroupBy(final Selectable groupBy) {
|
void setGroupBy(final Selectable groupBy) {
|
||||||
this.groupBy = groupBy;
|
this.groupBy = groupBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHaving(final Where having) {
|
void setHaving(final Expression having) {
|
||||||
this.having = having;
|
this.having = having;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSelect(final Selectable select) {
|
void setSelect(final Selectable select) {
|
||||||
this.select = select;
|
this.select = select;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWhere(final Where where) {
|
void setWhere(final Expression where) {
|
||||||
this.where = where;
|
this.where = where;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.mariotaku.querybuilder.query;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
|
import org.mariotaku.querybuilder.OnConflict;
|
||||||
|
import org.mariotaku.querybuilder.SQLQuery;
|
||||||
|
import org.mariotaku.querybuilder.SetValue;
|
||||||
|
import org.mariotaku.querybuilder.Utils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class SQLUpdateQuery implements SQLQuery {
|
||||||
|
|
||||||
|
private OnConflict onConflict;
|
||||||
|
private String table;
|
||||||
|
private SetValue[] values;
|
||||||
|
private Expression where;
|
||||||
|
|
||||||
|
SQLUpdateQuery() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
if (table == null) throw new NullPointerException("table must not be null!");
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("UPDATE ");
|
||||||
|
if (onConflict != null) {
|
||||||
|
sb.append(String.format(Locale.ROOT, "OR %s ", onConflict.getAction()));
|
||||||
|
}
|
||||||
|
sb.append(String.format(Locale.ROOT, "%s ", table));
|
||||||
|
sb.append(String.format(Locale.ROOT, "SET %s ", Utils.toString(values, ',', false)));
|
||||||
|
if (where != null) {
|
||||||
|
sb.append(String.format(Locale.ROOT, "WHERE %s ", where.getSQL()));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWhere(final Expression where) {
|
||||||
|
this.where = where;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValues(final SetValue[] columns) {
|
||||||
|
this.values = columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnConflict(final OnConflict onConflict) {
|
||||||
|
this.onConflict = onConflict;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTable(final String table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder implements IBuilder<SQLUpdateQuery> {
|
||||||
|
|
||||||
|
private final SQLUpdateQuery query = new SQLUpdateQuery();
|
||||||
|
|
||||||
|
private boolean buildCalled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLUpdateQuery build() {
|
||||||
|
buildCalled = true;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildSQL() {
|
||||||
|
return build().getSQL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder set(final SetValue... values) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setValues(values);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder where(final Expression where) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setWhere(where);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder update(final OnConflict onConflict, final String table) {
|
||||||
|
checkNotBuilt();
|
||||||
|
query.setOnConflict(onConflict);
|
||||||
|
query.setTable(table);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder update(final String table) {
|
||||||
|
return update(null, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNotBuilt() {
|
||||||
|
if (buildCalled) throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -175,7 +175,7 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
||||||
public static final int VIRTUAL_TABLE_ID_UNREAD_COUNTS_BY_TYPE = 109;
|
public static final int VIRTUAL_TABLE_ID_UNREAD_COUNTS_BY_TYPE = 109;
|
||||||
|
|
||||||
public static final int NOTIFICATION_ID_HOME_TIMELINE = 1;
|
public static final int NOTIFICATION_ID_HOME_TIMELINE = 1;
|
||||||
public static final int NOTIFICATION_ID_MENTIONS = 2;
|
public static final int NOTIFICATION_ID_MENTIONS_TIMELINE = 2;
|
||||||
public static final int NOTIFICATION_ID_DIRECT_MESSAGES = 3;
|
public static final int NOTIFICATION_ID_DIRECT_MESSAGES = 3;
|
||||||
public static final int NOTIFICATION_ID_DRAFTS = 4;
|
public static final int NOTIFICATION_ID_DRAFTS = 4;
|
||||||
public static final int NOTIFICATION_ID_DATA_PROFILING = 5;
|
public static final int NOTIFICATION_ID_DATA_PROFILING = 5;
|
||||||
|
|
|
@ -33,6 +33,7 @@ import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
@ -45,7 +46,7 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Where;
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
|
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
|
||||||
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
||||||
|
@ -83,25 +84,19 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(final Bundle savedInstanceState) {
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
super.onCreate(savedInstanceState);
|
getMenuInflater().inflate(R.menu.menu_filters, menu);
|
||||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
return true;
|
||||||
setContentView(R.layout.activity_filters);
|
|
||||||
mActionBar = getActionBar();
|
|
||||||
mAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), null);
|
|
||||||
mActionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
|
||||||
addTab(FilteredUsersFragment.class, R.string.users, 0);
|
|
||||||
addTab(FilteredKeywordsFragment.class, R.string.keywords, 1);
|
|
||||||
addTab(FilteredSourcesFragment.class, R.string.sources, 2);
|
|
||||||
addTab(FilteredLinksFragment.class, R.string.links, 3);
|
|
||||||
mViewPager.setAdapter(mAdapter);
|
|
||||||
mViewPager.setOnPageChangeListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
public boolean onPrepareOptionsMenu(final Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.menu_filters, menu);
|
final boolean enable_in_home_timeline = mPreferences.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||||
|
final boolean enable_in_mentions = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS_TIMELINE, true);
|
||||||
|
final boolean enable_for_rts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
|
||||||
|
menu.findItem(R.id.enable_in_home_timeline).setChecked(enable_in_home_timeline);
|
||||||
|
menu.findItem(R.id.enable_in_mentions).setChecked(enable_in_mentions);
|
||||||
|
menu.findItem(R.id.enable_for_rts).setChecked(enable_for_rts);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +135,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
}
|
}
|
||||||
case R.id.enable_in_mentions: {
|
case R.id.enable_in_mentions: {
|
||||||
final SharedPreferences.Editor editor = mPreferences.edit();
|
final SharedPreferences.Editor editor = mPreferences.edit();
|
||||||
editor.putBoolean(KEY_FILTERS_IN_MENTIONS, !item.isChecked());
|
editor.putBoolean(KEY_FILTERS_IN_MENTIONS_TIMELINE, !item.isChecked());
|
||||||
editor.apply();
|
editor.apply();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -155,12 +150,29 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||||
|
setContentView(R.layout.activity_filters);
|
||||||
|
mActionBar = getActionBar();
|
||||||
|
mAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), null);
|
||||||
|
mActionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||||
|
addTab(FilteredUsersFragment.class, R.string.users, 0);
|
||||||
|
addTab(FilteredKeywordsFragment.class, R.string.keywords, 1);
|
||||||
|
addTab(FilteredSourcesFragment.class, R.string.sources, 2);
|
||||||
|
addTab(FilteredLinksFragment.class, R.string.links, 3);
|
||||||
|
mViewPager.setAdapter(mAdapter);
|
||||||
|
mViewPager.setOnPageChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrollStateChanged(final int state) {
|
public boolean getSystemWindowsInsets(Rect insets) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -170,18 +182,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(final Menu menu) {
|
public void onPageScrollStateChanged(final int state) {
|
||||||
final boolean enable_in_home_timeline = mPreferences.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
|
||||||
final boolean enable_in_mentions = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS, true);
|
|
||||||
final boolean enable_for_rts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
|
|
||||||
menu.findItem(R.id.enable_in_home_timeline).setChecked(enable_in_home_timeline);
|
|
||||||
menu.findItem(R.id.enable_in_mentions).setChecked(enable_in_mentions);
|
|
||||||
menu.findItem(R.id.enable_for_rts).setChecked(enable_for_rts);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +196,11 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
|
@ -205,7 +211,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener,
|
||||||
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
|
final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
|
||||||
final ContentValues values = ContentValuesCreator.makeFilteredUserContentValues(user);
|
final ContentValues values = ContentValuesCreator.makeFilteredUserContentValues(user);
|
||||||
final ContentResolver resolver = getContentResolver();
|
final ContentResolver resolver = getContentResolver();
|
||||||
resolver.delete(Filters.Users.CONTENT_URI, Where.equals(Filters.Users.USER_ID, user.id).getSQL(), null);
|
resolver.delete(Filters.Users.CONTENT_URI, Expression.equals(Filters.Users.USER_ID, user.id).getSQL(), null);
|
||||||
resolver.insert(Filters.Users.CONTENT_URI, values);
|
resolver.insert(Filters.Users.CONTENT_URI, values);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import android.view.ViewGroup.MarginLayoutParams;
|
||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -235,7 +236,6 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||||
static final int HEADER_TYPE_CATEGORY = 1;
|
static final int HEADER_TYPE_CATEGORY = 1;
|
||||||
static final int HEADER_TYPE_SPACE = 2;
|
static final int HEADER_TYPE_SPACE = 2;
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final Resources mResources;
|
private final Resources mResources;
|
||||||
private final int mActionIconColor;
|
private final int mActionIconColor;
|
||||||
private final ArrayList<Header> mHeaders;
|
private final ArrayList<Header> mHeaders;
|
||||||
|
@ -244,7 +244,6 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||||
private boolean mFirstItemIsCategory;
|
private boolean mFirstItemIsCategory;
|
||||||
|
|
||||||
public HeaderAdapter(final Context context) {
|
public HeaderAdapter(final Context context) {
|
||||||
mContext = context;
|
|
||||||
mInflater = LayoutInflater.from(context);
|
mInflater = LayoutInflater.from(context);
|
||||||
mHeaders = new ArrayList<>();
|
mHeaders = new ArrayList<>();
|
||||||
mResources = context.getResources();
|
mResources = context.getResources();
|
||||||
|
@ -385,6 +384,13 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||||
holder.icon.setImageDrawable(null);
|
holder.icon.setImageDrawable(null);
|
||||||
}
|
}
|
||||||
holder.icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
|
holder.icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
|
||||||
|
|
||||||
|
if (position > 0 && position <= getCount() - 1) {
|
||||||
|
final boolean prevCategory = getItemViewType(position - 1) == HEADER_TYPE_CATEGORY;
|
||||||
|
holder.content.setShowDividers(prevCategory ? LinearLayout.SHOW_DIVIDER_NONE : LinearLayout.SHOW_DIVIDER_END);
|
||||||
|
} else {
|
||||||
|
holder.content.setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private View inflateItemView(int viewType, ViewGroup parent) {
|
private View inflateItemView(int viewType, ViewGroup parent) {
|
||||||
|
@ -424,12 +430,14 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||||
private static class HeaderViewHolder extends ViewHolder {
|
private static class HeaderViewHolder extends ViewHolder {
|
||||||
private final TextView title, summary;
|
private final TextView title, summary;
|
||||||
private final ImageView icon;
|
private final ImageView icon;
|
||||||
|
private final LinearLayout content;
|
||||||
|
|
||||||
HeaderViewHolder(final View view) {
|
HeaderViewHolder(final View view) {
|
||||||
super(view);
|
super(view);
|
||||||
title = (TextView) findViewById(android.R.id.title);
|
title = (TextView) findViewById(android.R.id.title);
|
||||||
summary = (TextView) findViewById(android.R.id.summary);
|
summary = (TextView) findViewById(android.R.id.summary);
|
||||||
icon = (ImageView) findViewById(android.R.id.icon);
|
icon = (ImageView) findViewById(android.R.id.icon);
|
||||||
|
content = (LinearLayout) findViewById(android.R.id.content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,8 @@ import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.BaseArrayAdapter;
|
import org.mariotaku.twidere.adapter.BaseArrayAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||||
import org.mariotaku.twidere.model.Account;
|
|
||||||
import org.mariotaku.twidere.model.DraftItem;
|
import org.mariotaku.twidere.model.DraftItem;
|
||||||
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.ParcelableLocation;
|
import org.mariotaku.twidere.model.ParcelableLocation;
|
||||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
|
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
|
||||||
|
@ -186,7 +186,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
|
|
||||||
private boolean mIsPossiblySensitive, mShouldSaveAccounts;
|
private boolean mIsPossiblySensitive, mShouldSaveAccounts;
|
||||||
|
|
||||||
private long[] mAccountIds, mSendAccountIds;
|
private long[] mSendAccountIds;
|
||||||
|
|
||||||
private Uri mTempPhotoUri;
|
private Uri mTempPhotoUri;
|
||||||
private boolean mImageUploaderUsed, mStatusShortenerUsed;
|
private boolean mImageUploaderUsed, mStatusShortenerUsed;
|
||||||
|
@ -537,7 +537,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
public void saveToDrafts() {
|
public void saveToDrafts() {
|
||||||
final String text = mEditText != null ? ParseUtils.parseString(mEditText.getText()) : null;
|
final String text = mEditText != null ? ParseUtils.parseString(mEditText.getText()) : null;
|
||||||
final ParcelableStatusUpdate.Builder builder = new ParcelableStatusUpdate.Builder();
|
final ParcelableStatusUpdate.Builder builder = new ParcelableStatusUpdate.Builder();
|
||||||
builder.accounts(Account.getAccounts(this, mSendAccountIds));
|
builder.accounts(ParcelableAccount.getAccounts(this, mSendAccountIds));
|
||||||
builder.text(text);
|
builder.text(text);
|
||||||
builder.inReplyToStatusId(mInReplyToStatusId);
|
builder.inReplyToStatusId(mInReplyToStatusId);
|
||||||
builder.location(mRecentLocation);
|
builder.location(mRecentLocation);
|
||||||
|
@ -561,8 +561,8 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
setContentView(R.layout.activity_compose);
|
setContentView(R.layout.activity_compose);
|
||||||
setProgressBarIndeterminateVisibility(false);
|
setProgressBarIndeterminateVisibility(false);
|
||||||
setFinishOnTouchOutside(false);
|
setFinishOnTouchOutside(false);
|
||||||
mAccountIds = getAccountIds(this);
|
final long[] defaultAccountIds = getAccountIds(this);
|
||||||
if (mAccountIds.length <= 0) {
|
if (defaultAccountIds.length <= 0) {
|
||||||
final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
|
final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
|
||||||
intent.setClass(this, SignInActivity.class);
|
intent.setClass(this, SignInActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
@ -574,7 +574,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
mEditText.setOnEditorActionListener(mPreferences.getBoolean(KEY_QUICK_SEND, false) ? this : null);
|
mEditText.setOnEditorActionListener(mPreferences.getBoolean(KEY_QUICK_SEND, false) ? this : null);
|
||||||
mEditText.addTextChangedListener(this);
|
mEditText.addTextChangedListener(this);
|
||||||
final AccountSelectorAdapter accountAdapter = new AccountSelectorAdapter(mMenuBar.getPopupContext());
|
final AccountSelectorAdapter accountAdapter = new AccountSelectorAdapter(mMenuBar.getPopupContext());
|
||||||
accountAdapter.addAll(Account.getAccountsList(this, false));
|
accountAdapter.addAll(ParcelableAccount.getAccountsList(this, false));
|
||||||
mAccountSelectorPopup = IListPopupWindow.InstanceHelper.getInstance(mMenuBar.getPopupContext());
|
mAccountSelectorPopup = IListPopupWindow.InstanceHelper.getInstance(mMenuBar.getPopupContext());
|
||||||
mAccountSelectorPopup.setInputMethodMode(IListPopupWindow.INPUT_METHOD_NOT_NEEDED);
|
mAccountSelectorPopup.setInputMethodMode(IListPopupWindow.INPUT_METHOD_NOT_NEEDED);
|
||||||
mAccountSelectorPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
mAccountSelectorPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||||
|
@ -621,8 +621,8 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
if (mSendAccountIds == null || mSendAccountIds.length == 0) {
|
if (mSendAccountIds == null || mSendAccountIds.length == 0) {
|
||||||
final long[] idsInPrefs = ArrayUtils.parseLongArray(
|
final long[] idsInPrefs = ArrayUtils.parseLongArray(
|
||||||
mPreferences.getString(KEY_COMPOSE_ACCOUNTS, null), ',');
|
mPreferences.getString(KEY_COMPOSE_ACCOUNTS, null), ',');
|
||||||
final long[] intersection = ArrayUtils.intersection(idsInPrefs, mAccountIds);
|
final long[] intersection = ArrayUtils.intersection(idsInPrefs, defaultAccountIds);
|
||||||
mSendAccountIds = intersection.length > 0 ? intersection : mAccountIds;
|
mSendAccountIds = intersection.length > 0 ? intersection : defaultAccountIds;
|
||||||
}
|
}
|
||||||
mOriginalText = ParseUtils.parseString(mEditText.getText());
|
mOriginalText = ParseUtils.parseString(mEditText.getText());
|
||||||
}
|
}
|
||||||
|
@ -732,7 +732,18 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
private boolean handleDefaultIntent(final Intent intent) {
|
private boolean handleDefaultIntent(final Intent intent) {
|
||||||
if (intent == null) return false;
|
if (intent == null) return false;
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
mShouldSaveAccounts = !Intent.ACTION_SEND.equals(action) && !Intent.ACTION_SEND_MULTIPLE.equals(action);
|
final boolean hasAccountIds;
|
||||||
|
if (intent.hasExtra(EXTRA_ACCOUNT_IDS)) {
|
||||||
|
mSendAccountIds = intent.getLongArrayExtra(EXTRA_ACCOUNT_IDS);
|
||||||
|
hasAccountIds = true;
|
||||||
|
} else if (intent.hasExtra(EXTRA_ACCOUNT_ID)) {
|
||||||
|
mSendAccountIds = new long[]{intent.getLongExtra(EXTRA_ACCOUNT_ID, -1)};
|
||||||
|
hasAccountIds = true;
|
||||||
|
} else {
|
||||||
|
hasAccountIds = false;
|
||||||
|
}
|
||||||
|
mShouldSaveAccounts = !Intent.ACTION_SEND.equals(action)
|
||||||
|
&& !Intent.ACTION_SEND_MULTIPLE.equals(action) && !hasAccountIds;
|
||||||
final Uri data = intent.getData();
|
final Uri data = intent.getData();
|
||||||
final CharSequence extraSubject = intent.getCharSequenceExtra(Intent.EXTRA_SUBJECT);
|
final CharSequence extraSubject = intent.getCharSequenceExtra(Intent.EXTRA_SUBJECT);
|
||||||
final CharSequence extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
|
final CharSequence extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
|
||||||
|
@ -1265,7 +1276,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AccountSelectorAdapter extends BaseArrayAdapter<Account> {
|
private static class AccountSelectorAdapter extends BaseArrayAdapter<ParcelableAccount> {
|
||||||
|
|
||||||
public AccountSelectorAdapter(final Context context) {
|
public AccountSelectorAdapter(final Context context) {
|
||||||
super(context, android.R.layout.simple_list_item_multiple_choice);
|
super(context, android.R.layout.simple_list_item_multiple_choice);
|
||||||
|
@ -1284,7 +1295,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
final View view = super.getView(position, convertView, parent);
|
final View view = super.getView(position, convertView, parent);
|
||||||
final Account account = getItem(position);
|
final ParcelableAccount account = getItem(position);
|
||||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||||
text1.setText(Utils.getAccountDisplayName(getContext(), account.account_id, isDisplayNameFirst()));
|
text1.setText(Utils.getAccountDisplayName(getContext(), account.account_id, isDisplayNameFirst()));
|
||||||
return view;
|
return view;
|
||||||
|
|
|
@ -48,7 +48,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
|
||||||
import org.mariotaku.twidere.adapter.ArrayAdapter;
|
import org.mariotaku.twidere.adapter.ArrayAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
||||||
import org.mariotaku.twidere.model.CustomTabConfiguration.ExtraConfiguration;
|
import org.mariotaku.twidere.model.CustomTabConfiguration.ExtraConfiguration;
|
||||||
import org.mariotaku.twidere.model.ParcelableUser;
|
import org.mariotaku.twidere.model.ParcelableUser;
|
||||||
|
@ -303,10 +303,10 @@ public class CustomTabEditorActivity extends BaseSupportDialogActivity implement
|
||||||
mSecondaryFieldContainer.setVisibility(has_secondary_field ? View.VISIBLE : View.GONE);
|
mSecondaryFieldContainer.setVisibility(has_secondary_field ? View.VISIBLE : View.GONE);
|
||||||
final boolean accountIdRequired = conf.getAccountRequirement() == CustomTabConfiguration.ACCOUNT_REQUIRED;
|
final boolean accountIdRequired = conf.getAccountRequirement() == CustomTabConfiguration.ACCOUNT_REQUIRED;
|
||||||
if (!accountIdRequired) {
|
if (!accountIdRequired) {
|
||||||
mAccountsAdapter.add(Account.dummyInstance());
|
mAccountsAdapter.add(ParcelableAccount.dummyInstance());
|
||||||
}
|
}
|
||||||
final boolean officialKeyOnly = intent.getBooleanExtra(EXTRA_OFFICIAL_KEY_ONLY, false);
|
final boolean officialKeyOnly = intent.getBooleanExtra(EXTRA_OFFICIAL_KEY_ONLY, false);
|
||||||
mAccountsAdapter.addAll(Account.getAccountsList(this, false, officialKeyOnly));
|
mAccountsAdapter.addAll(ParcelableAccount.getAccountsList(this, false, officialKeyOnly));
|
||||||
switch (conf.getSecondaryFieldType()) {
|
switch (conf.getSecondaryFieldType()) {
|
||||||
case CustomTabConfiguration.FIELD_TYPE_USER: {
|
case CustomTabConfiguration.FIELD_TYPE_USER: {
|
||||||
mSecondaryFieldLabel.setText(R.string.user);
|
mSecondaryFieldLabel.setText(R.string.user);
|
||||||
|
|
|
@ -50,8 +50,8 @@ import android.widget.ListView;
|
||||||
|
|
||||||
import org.mariotaku.menucomponent.widget.PopupMenu;
|
import org.mariotaku.menucomponent.widget.PopupMenu;
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.DraftsAdapter;
|
import org.mariotaku.twidere.adapter.DraftsAdapter;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||||
|
@ -106,7 +106,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendDrafts(list)) {
|
if (sendDrafts(list)) {
|
||||||
final Where where = Where.in(new Column(Drafts._ID),
|
final Expression where = Expression.in(new Column(Drafts._ID),
|
||||||
new RawItemArray(mListView.getCheckedItemIds()));
|
new RawItemArray(mListView.getCheckedItemIds()));
|
||||||
mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac
|
||||||
final Bundle bundle = new Bundle();
|
final Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable(EXTRA_DRAFT, draft);
|
bundle.putParcelable(EXTRA_DRAFT, draft);
|
||||||
intent.putExtras(bundle);
|
intent.putExtras(bundle);
|
||||||
mResolver.delete(Drafts.CONTENT_URI, Where.equals(Drafts._ID, draft._id).getSQL(), null);
|
mResolver.delete(Drafts.CONTENT_URI, Expression.equals(Drafts._ID, draft._id).getSQL(), null);
|
||||||
startActivityForResult(intent, REQUEST_COMPOSE);
|
startActivityForResult(intent, REQUEST_COMPOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac
|
||||||
@Override
|
@Override
|
||||||
protected Integer doInBackground(final Void... params) {
|
protected Integer doInBackground(final Void... params) {
|
||||||
final ContentResolver resolver = mActivity.getContentResolver();
|
final ContentResolver resolver = mActivity.getContentResolver();
|
||||||
final Where where = Where.in(new Column(Drafts._ID), new RawItemArray(mIds));
|
final Expression where = Expression.in(new Column(Drafts._ID), new RawItemArray(mIds));
|
||||||
final String[] projection = {Drafts.MEDIA};
|
final String[] projection = {Drafts.MEDIA};
|
||||||
final Cursor c = resolver.query(Drafts.CONTENT_URI, projection, where.getSQL(), null, null);
|
final Cursor c = resolver.query(Drafts.CONTENT_URI, projection, where.getSQL(), null, null);
|
||||||
final int idxMedia = c.getColumnIndex(Drafts.MEDIA);
|
final int idxMedia = c.getColumnIndex(Drafts.MEDIA);
|
||||||
|
|
|
@ -77,7 +77,7 @@ import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||||
import org.mariotaku.twidere.graphic.EmptyDrawable;
|
import org.mariotaku.twidere.graphic.EmptyDrawable;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.SupportTabSpec;
|
import org.mariotaku.twidere.model.SupportTabSpec;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
import org.mariotaku.twidere.task.AsyncTask;
|
||||||
|
@ -146,7 +146,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
||||||
private final ArrayList<SupportTabSpec> mCustomTabs = new ArrayList<SupportTabSpec>();
|
private final ArrayList<SupportTabSpec> mCustomTabs = new ArrayList<SupportTabSpec>();
|
||||||
|
|
||||||
private final SparseArray<Fragment> mAttachedFragments = new SparseArray<Fragment>();
|
private final SparseArray<Fragment> mAttachedFragments = new SparseArray<Fragment>();
|
||||||
private Account mSelectedAccountToSearch;
|
private ParcelableAccount mSelectedAccountToSearch;
|
||||||
|
|
||||||
private SharedPreferences mPreferences;
|
private SharedPreferences mPreferences;
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openSearchView(final Account account) {
|
public void openSearchView(final ParcelableAccount account) {
|
||||||
mSelectedAccountToSearch = account;
|
mSelectedAccountToSearch = account;
|
||||||
onSearchRequested();
|
onSearchRequested();
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,8 +210,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LINK_ID_STATUS: {
|
case LINK_ID_STATUS: {
|
||||||
// transitionRes = R.transition.transition_status;
|
transitionRes = R.transition.transition_status;
|
||||||
transitionRes = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -221,7 +220,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
|
||||||
}
|
}
|
||||||
if (transitionRes != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
if (transitionRes != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||||
&& !ThemeUtils.isTransparentBackground(this)) {
|
&& !ThemeUtils.isTransparentBackground(this)) {
|
||||||
Utils.setSharedElementTransition(this, window, R.transition.transition_status);
|
Utils.setSharedElementTransition(this, window, transitionRes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.fragment.support.StatusFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.StatusMenuDialogFragment;
|
import org.mariotaku.twidere.fragment.support.StatusMenuDialogFragment;
|
||||||
import org.mariotaku.twidere.fragment.support.UserFragment;
|
import org.mariotaku.twidere.fragment.support.UserFragment;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
@ -42,6 +41,8 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
||||||
private final int mCardLayoutResource;
|
private final int mCardLayoutResource;
|
||||||
private boolean mLoadMoreIndicatorEnabled;
|
private boolean mLoadMoreIndicatorEnabled;
|
||||||
|
|
||||||
|
private EventListener mEventListener;
|
||||||
|
|
||||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mInflater = LayoutInflater.from(context);
|
mInflater = LayoutInflater.from(context);
|
||||||
|
@ -59,7 +60,7 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
case ITEM_VIEW_TYPE_STATUS: {
|
case ITEM_VIEW_TYPE_STATUS: {
|
||||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||||
return new StatusViewHolder<>(this, view);
|
return new StatusViewHolder(this, view);
|
||||||
}
|
}
|
||||||
case ITEM_VIEW_TYPE_GAP: {
|
case ITEM_VIEW_TYPE_GAP: {
|
||||||
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);
|
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);
|
||||||
|
@ -126,16 +127,10 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
public final void onStatusClick(StatusViewHolder holder, int position) {
|
||||||
final Context context = getContext();
|
if (mEventListener != null) {
|
||||||
// final View cardView = holder.getCardView();
|
mEventListener.onStatusClick(holder, position);
|
||||||
// if (cardView != null && context instanceof FragmentActivity) {
|
}
|
||||||
// final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
|
||||||
// new Pair<>(cardView, StatusFragment.TRANSITION_NAME_CARD));
|
|
||||||
// Utils.openStatus(context, getStatus(position), options);
|
|
||||||
// } else {
|
|
||||||
Utils.openStatus(context, getStatus(position), null);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,18 +148,42 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||||
final Context context = getContext();
|
if (mEventListener != null) {
|
||||||
if (!(context instanceof FragmentActivity)) return;
|
mEventListener.onStatusActionClick((StatusViewHolder) holder, id, position);
|
||||||
final Bundle args = new Bundle();
|
}
|
||||||
args.putParcelable(EXTRA_STATUS, getStatus(position));
|
}
|
||||||
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
|
||||||
f.setArguments(args);
|
@Override
|
||||||
f.show(((FragmentActivity) context).getSupportFragmentManager(), "status_menu");
|
public void onItemMenuClick(ViewHolder holder, int position) {
|
||||||
|
if (mEventListener != null) {
|
||||||
|
mEventListener.onStatusMenuClick((StatusViewHolder) holder, position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void setData(D data);
|
public abstract void setData(D data);
|
||||||
|
|
||||||
public abstract D getData();
|
public abstract D getData();
|
||||||
|
|
||||||
|
public void setEventListener(EventListener listener) {
|
||||||
|
mEventListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onGapClick(ViewHolder holder, int position) {
|
||||||
|
if (mEventListener != null) {
|
||||||
|
mEventListener.onGapClick((GapViewHolder) holder, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface EventListener {
|
||||||
|
void onStatusActionClick(StatusViewHolder holder, int id, int position);
|
||||||
|
|
||||||
|
void onStatusClick(StatusViewHolder holder, int position);
|
||||||
|
|
||||||
|
void onGapClick(GapViewHolder holder, int position);
|
||||||
|
|
||||||
|
void onStatusMenuClick(StatusViewHolder holder, int position);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
|
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.Account.Indices;
|
import org.mariotaku.twidere.model.ParcelableAccount.Indices;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||||
import org.mariotaku.twidere.view.holder.AccountViewHolder;
|
import org.mariotaku.twidere.view.holder.AccountViewHolder;
|
||||||
|
@ -58,10 +58,10 @@ public class AccountsAdapter extends SimpleDragSortCursorAdapter implements Cons
|
||||||
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount(int position) {
|
public ParcelableAccount getAccount(int position) {
|
||||||
final Cursor c = getCursor();
|
final Cursor c = getCursor();
|
||||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
|
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
|
||||||
return new Account(c, mIndices);
|
return new ParcelableAccount(c, mIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.mariotaku.twidere.adapter;
|
package org.mariotaku.twidere.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.PorterDuff.Mode;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
@ -29,13 +28,12 @@ import android.widget.TextView;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.fragment.support.DirectMessagesConversationFragment;
|
import org.mariotaku.twidere.fragment.support.DirectMessagesConversationFragment;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||||
import org.mariotaku.twidere.util.ThemeUtils;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class AccountsSpinnerAdapter extends ArrayAdapter<Account> {
|
public class AccountsSpinnerAdapter extends ArrayAdapter<ParcelableAccount> {
|
||||||
|
|
||||||
private final ImageLoaderWrapper mImageLoader;
|
private final ImageLoaderWrapper mImageLoader;
|
||||||
private final boolean mDisplayProfileImage;
|
private final boolean mDisplayProfileImage;
|
||||||
|
@ -48,7 +46,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<Account> {
|
||||||
Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true);
|
Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountsSpinnerAdapter(final Context context, final Collection<Account> accounts) {
|
public AccountsSpinnerAdapter(final Context context, final Collection<ParcelableAccount> accounts) {
|
||||||
this(context);
|
this(context);
|
||||||
addAll(accounts);
|
addAll(accounts);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +65,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<Account> {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindView(final View view, final Account item) {
|
private void bindView(final View view, final ParcelableAccount item) {
|
||||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||||
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||||
|
|
|
@ -73,11 +73,6 @@ public class CursorStatusesAdapter extends AbsStatusesAdapter<Cursor> {
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGapClick(StatusViewHolder holder, int position) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor getData() {
|
public Cursor getData() {
|
||||||
return mCursor;
|
return mCursor;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
|
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -121,7 +122,12 @@ public class CursorStatusesListAdapter extends BaseCursorAdapter implements ISta
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemMenuClick(ViewHolder holder, int position) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +370,7 @@ public class CursorStatusesListAdapter extends BaseCursorAdapter implements ISta
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGapClick(StatusViewHolder holder, int position) {
|
public void onGapClick(ViewHolder holder, int position) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries;
|
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries;
|
||||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||||
import org.mariotaku.twidere.util.Utils;
|
|
||||||
import org.mariotaku.twidere.view.holder.DirectMessageEntryViewHolder;
|
import org.mariotaku.twidere.view.holder.DirectMessageEntryViewHolder;
|
||||||
|
|
||||||
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_ACCOUNT_ID;
|
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_ACCOUNT_ID;
|
||||||
|
@ -55,15 +54,8 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||||
private final ImageLoaderWrapper mImageLoader;
|
private final ImageLoaderWrapper mImageLoader;
|
||||||
private final MultiSelectManager mMultiSelectManager;
|
private final MultiSelectManager mMultiSelectManager;
|
||||||
|
|
||||||
private boolean mAnimationEnabled;
|
|
||||||
private int mMaxAnimationPosition;
|
|
||||||
|
|
||||||
public DirectMessageConversationEntriesAdapter(final Context context) {
|
public DirectMessageConversationEntriesAdapter(final Context context) {
|
||||||
this(context, Utils.isCompactCards(context));
|
super(context, R.layout.list_item_message_entry, null, new String[0], new int[0], 0);
|
||||||
}
|
|
||||||
|
|
||||||
public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards) {
|
|
||||||
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
|
|
||||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||||
mMultiSelectManager = app.getMultiSelectManager();
|
mMultiSelectManager = app.getMultiSelectManager();
|
||||||
mImageLoader = app.getImageLoaderWrapper();
|
mImageLoader = app.getImageLoaderWrapper();
|
||||||
|
@ -96,8 +88,6 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||||
final String nick = getUserNickname(context, conversationId);
|
final String nick = getUserNickname(context, conversationId);
|
||||||
holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString(
|
holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString(
|
||||||
R.string.name_with_nickname, name, nick));
|
R.string.name_with_nickname, name, nick));
|
||||||
holder.screen_name.setText("@" + screenName);
|
|
||||||
holder.screen_name.setVisibility(View.VISIBLE);
|
|
||||||
holder.text.setText(toPlainText(cursor.getString(IDX_TEXT)));
|
holder.text.setText(toPlainText(cursor.getString(IDX_TEXT)));
|
||||||
holder.time.setTime(timestamp);
|
holder.time.setTime(timestamp);
|
||||||
holder.setIsOutgoing(isOutgoing);
|
holder.setIsOutgoing(isOutgoing);
|
||||||
|
@ -110,12 +100,6 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||||
} else {
|
} else {
|
||||||
mImageLoader.cancelDisplayTask(holder.profile_image);
|
mImageLoader.cancelDisplayTask(holder.profile_image);
|
||||||
}
|
}
|
||||||
if (position > mMaxAnimationPosition) {
|
|
||||||
if (mAnimationEnabled) {
|
|
||||||
view.startAnimation(holder.item_animation);
|
|
||||||
}
|
|
||||||
mMaxAnimationPosition = position;
|
|
||||||
}
|
|
||||||
super.bindView(view, context, cursor);
|
super.bindView(view, context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,20 +159,14 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAnimationEnabled(final boolean anim) {
|
public void setAnimationEnabled(final boolean anim) {
|
||||||
if (mAnimationEnabled == anim) return;
|
|
||||||
mAnimationEnabled = anim;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMaxAnimationPosition(final int position) {
|
public void setMaxAnimationPosition(final int position) {
|
||||||
mMaxAnimationPosition = position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getItemResource(final boolean compactCards) {
|
|
||||||
return compactCards ? R.layout.card_item_message_entry_compact : R.layout.card_item_message_entry;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,6 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter<List<Parcelabl
|
||||||
return getStatus(position).is_gap;
|
return getStatus(position).is_gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGapClick(StatusViewHolder holder, int position) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||||
holder.displayStatus(getStatus(position));
|
holder.displayStatus(getStatus(position));
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -105,7 +106,12 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemMenuClick(ViewHolder holder, int position) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +190,7 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGapClick(StatusViewHolder holder, int position) {
|
public void onGapClick(ViewHolder holder, int position) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
|
@ -169,7 +169,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
||||||
builder.append(" OR ");
|
builder.append(" OR ");
|
||||||
builder.append(CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'");
|
builder.append(CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'");
|
||||||
builder.append(" OR ");
|
builder.append(" OR ");
|
||||||
builder.append(Where.in(new Column(CachedUsers.USER_ID),
|
builder.append(Expression.in(new Column(CachedUsers.USER_ID),
|
||||||
new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL());
|
new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL());
|
||||||
final String selection = constraint_escaped != null ? builder.toString() : null;
|
final String selection = constraint_escaped != null ? builder.toString() : null;
|
||||||
final String[] selectionArgs = constraint_escaped != null ? new String[]{constraint_escaped,
|
final String[] selectionArgs = constraint_escaped != null ? new String[]{constraint_escaped,
|
||||||
|
|
|
@ -24,6 +24,8 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/12/3.
|
* Created by mariotaku on 14/12/3.
|
||||||
*/
|
*/
|
||||||
public interface IItemMenuSupportedAdapter<VH extends ViewHolder> {
|
public interface ICardSupportedAdapter {
|
||||||
void onItemMenuClick(VH holder, int position);
|
void onItemActionClick(ViewHolder holder, int id, int position);
|
||||||
|
|
||||||
|
void onItemMenuClick(ViewHolder holder, int position);
|
||||||
}
|
}
|
|
@ -24,10 +24,10 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/12/3.
|
* Created by mariotaku on 14/12/3.
|
||||||
*/
|
*/
|
||||||
public interface IGapSupportedAdapter<VH extends ViewHolder> {
|
public interface IGapSupportedAdapter {
|
||||||
|
|
||||||
boolean isGapItem(int position);
|
boolean isGapItem(int position);
|
||||||
|
|
||||||
void onGapClick(VH holder, int position);
|
void onGapClick(ViewHolder holder, int position);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/11/18.
|
* Created by mariotaku on 14/11/18.
|
||||||
*/
|
*/
|
||||||
public interface IStatusesAdapter<Data> extends IGapSupportedAdapter<StatusViewHolder>,
|
public interface IStatusesAdapter<Data> extends IGapSupportedAdapter, ICardSupportedAdapter {
|
||||||
IItemMenuSupportedAdapter<StatusViewHolder> {
|
|
||||||
|
|
||||||
ImageLoaderWrapper getImageLoader();
|
ImageLoaderWrapper getImageLoader();
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ public interface IntentConstants {
|
||||||
public static final String BROADCAST_FRIENDSHIP_DENIED = INTENT_PACKAGE_PREFIX + "FRIENDSHIP_DENIED";
|
public static final String BROADCAST_FRIENDSHIP_DENIED = INTENT_PACKAGE_PREFIX + "FRIENDSHIP_DENIED";
|
||||||
|
|
||||||
public static final String BROADCAST_FAVORITE_CHANGED = INTENT_PACKAGE_PREFIX + "FAVORITE_CHANGED";
|
public static final String BROADCAST_FAVORITE_CHANGED = INTENT_PACKAGE_PREFIX + "FAVORITE_CHANGED";
|
||||||
public static final String BROADCAST_RETWEET_CHANGED = INTENT_PACKAGE_PREFIX + "RETWEET_CHANGED";
|
public static final String BROADCAST_STATUS_RETWEETED = INTENT_PACKAGE_PREFIX + "STATUS_RETWEETED";
|
||||||
public static final String BROADCAST_STATUS_DESTROYED = INTENT_PACKAGE_PREFIX + "STATUS_DESTROYED";
|
public static final String BROADCAST_STATUS_DESTROYED = INTENT_PACKAGE_PREFIX + "STATUS_DESTROYED";
|
||||||
public static final String BROADCAST_USER_LIST_MEMBERS_DELETED = INTENT_PACKAGE_PREFIX + "USER_LIST_MEMBER_DELETED";
|
public static final String BROADCAST_USER_LIST_MEMBERS_DELETED = INTENT_PACKAGE_PREFIX + "USER_LIST_MEMBER_DELETED";
|
||||||
public static final String BROADCAST_USER_LIST_MEMBERS_ADDED = INTENT_PACKAGE_PREFIX + "USER_LIST_MEMBER_ADDED";
|
public static final String BROADCAST_USER_LIST_MEMBERS_ADDED = INTENT_PACKAGE_PREFIX + "USER_LIST_MEMBER_ADDED";
|
||||||
|
|
|
@ -253,7 +253,7 @@ public interface SharedPreferenceConstants {
|
||||||
@Preference(type = STRING, hasDefault = true, defaultString = TwidereConstants.TWITTER_CONSUMER_SECRET_3)
|
@Preference(type = STRING, hasDefault = true, defaultString = TwidereConstants.TWITTER_CONSUMER_SECRET_3)
|
||||||
public static final String KEY_CONSUMER_SECRET = "consumer_secret";
|
public static final String KEY_CONSUMER_SECRET = "consumer_secret";
|
||||||
public static final String KEY_FILTERS_IN_HOME_TIMELINE = "filters_in_home_timeline";
|
public static final String KEY_FILTERS_IN_HOME_TIMELINE = "filters_in_home_timeline";
|
||||||
public static final String KEY_FILTERS_IN_MENTIONS = "filters_in_mentions";
|
public static final String KEY_FILTERS_IN_MENTIONS_TIMELINE = "filters_in_mentions";
|
||||||
public static final String KEY_FILTERS_FOR_RTS = "filters_for_rts";
|
public static final String KEY_FILTERS_FOR_RTS = "filters_for_rts";
|
||||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||||
public static final String KEY_NICKNAME_ONLY = "nickname_only";
|
public static final String KEY_NICKNAME_ONLY = "nickname_only";
|
||||||
|
|
|
@ -23,7 +23,7 @@ import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
|
|
||||||
public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFragment {
|
public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFragment {
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFr
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
final Preference preference = findPreference(KEY_NOTIFICATION_LIGHT_COLOR);
|
final Preference preference = findPreference(KEY_NOTIFICATION_LIGHT_COLOR);
|
||||||
final Account account = getAccount();
|
final ParcelableAccount account = getAccount();
|
||||||
if (preference != null && account != null) {
|
if (preference != null && account != null) {
|
||||||
preference.setDefaultValue(account.color);
|
preference.setDefaultValue(account.color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ import android.widget.Switch;
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
|
|
||||||
public abstract class BaseAccountPreferenceFragment extends PreferenceFragment implements Constants,
|
public abstract class BaseAccountPreferenceFragment extends PreferenceFragment implements Constants,
|
||||||
OnCheckedChangeListener, OnSharedPreferenceChangeListener {
|
OnCheckedChangeListener, OnSharedPreferenceChangeListener {
|
||||||
|
@ -49,7 +49,7 @@ public abstract class BaseAccountPreferenceFragment extends PreferenceFragment i
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
final PreferenceManager pm = getPreferenceManager();
|
final PreferenceManager pm = getPreferenceManager();
|
||||||
final Account account = getArguments().getParcelable(EXTRA_ACCOUNT);
|
final ParcelableAccount account = getArguments().getParcelable(EXTRA_ACCOUNT);
|
||||||
final String preferenceName = ACCOUNT_PREFERENCES_NAME_PREFIX
|
final String preferenceName = ACCOUNT_PREFERENCES_NAME_PREFIX
|
||||||
+ (account != null ? account.account_id : "unknown");
|
+ (account != null ? account.account_id : "unknown");
|
||||||
pm.setSharedPreferencesName(preferenceName);
|
pm.setSharedPreferencesName(preferenceName);
|
||||||
|
@ -93,7 +93,7 @@ public abstract class BaseAccountPreferenceFragment extends PreferenceFragment i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Account getAccount() {
|
protected ParcelableAccount getAccount() {
|
||||||
final Bundle args = getArguments();
|
final Bundle args = getArguments();
|
||||||
if (args == null) return null;
|
if (args == null) return null;
|
||||||
return args.getParcelable(EXTRA_ACCOUNT);
|
return args.getParcelable(EXTRA_ACCOUNT);
|
||||||
|
|
|
@ -45,8 +45,8 @@ import android.widget.SimpleCursorAdapter;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.fragment.support.BaseSupportListFragment;
|
import org.mariotaku.twidere.fragment.support.BaseSupportListFragment;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
||||||
|
@ -83,7 +83,7 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
|
||||||
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
|
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_DELETE: {
|
case MENU_DELETE: {
|
||||||
final Where where = Where.in(new Column(Filters._ID), new RawItemArray(mListView.getCheckedItemIds()));
|
final Expression where = Expression.in(new Column(Filters._ID), new RawItemArray(mListView.getCheckedItemIds()));
|
||||||
mResolver.delete(getContentUri(), where.getSQL(), null);
|
mResolver.delete(getContentUri(), where.getSQL(), null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ import com.mobeta.android.dslv.SimpleDragSortCursorAdapter;
|
||||||
|
|
||||||
import org.mariotaku.menucomponent.widget.PopupMenu;
|
import org.mariotaku.menucomponent.widget.PopupMenu;
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.support.CustomTabEditorActivity;
|
import org.mariotaku.twidere.activity.support.CustomTabEditorActivity;
|
||||||
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
||||||
|
@ -101,7 +101,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
|
||||||
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
|
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_DELETE: {
|
case MENU_DELETE: {
|
||||||
final Where where = Where.in(new Column(Tabs._ID), new RawItemArray(mListView.getCheckedItemIds()));
|
final Expression where = Expression.in(new Column(Tabs._ID), new RawItemArray(mListView.getCheckedItemIds()));
|
||||||
mResolver.delete(Tabs.CONTENT_URI, where.getSQL(), null);
|
mResolver.delete(Tabs.CONTENT_URI, where.getSQL(), null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba
|
||||||
values.put(Tabs.NAME, data.getStringExtra(EXTRA_NAME));
|
values.put(Tabs.NAME, data.getStringExtra(EXTRA_NAME));
|
||||||
values.put(Tabs.ICON, data.getStringExtra(EXTRA_ICON));
|
values.put(Tabs.ICON, data.getStringExtra(EXTRA_ICON));
|
||||||
values.put(Tabs.EXTRAS, data.getStringExtra(EXTRA_EXTRAS));
|
values.put(Tabs.EXTRAS, data.getStringExtra(EXTRA_EXTRAS));
|
||||||
final String where = Where.equals(Tabs._ID, data.getLongExtra(EXTRA_ID, -1)).getSQL();
|
final String where = Expression.equals(Tabs._ID, data.getLongExtra(EXTRA_ID, -1)).getSQL();
|
||||||
mResolver.update(Tabs.CONTENT_URI, values, where, null);
|
mResolver.update(Tabs.CONTENT_URI, values, where, null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.LoaderManager;
|
|
||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
|
@ -19,27 +21,77 @@ import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
||||||
|
import org.mariotaku.twidere.adapter.AbsStatusesAdapter.EventListener;
|
||||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||||
|
import org.mariotaku.twidere.constant.IntentConstants;
|
||||||
|
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||||
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||||
import org.mariotaku.twidere.util.SimpleDrawerCallback;
|
import org.mariotaku.twidere.util.SimpleDrawerCallback;
|
||||||
import org.mariotaku.twidere.util.ThemeUtils;
|
import org.mariotaku.twidere.util.ThemeUtils;
|
||||||
import org.mariotaku.twidere.util.Utils;
|
import org.mariotaku.twidere.util.Utils;
|
||||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||||
|
import org.mariotaku.twidere.view.holder.GapViewHolder;
|
||||||
|
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/11/5.
|
* Created by mariotaku on 14/11/5.
|
||||||
*/
|
*/
|
||||||
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment
|
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment implements LoaderCallbacks<Data>,
|
||||||
implements LoaderCallbacks<Data>, OnRefreshListener, DrawerCallback {
|
OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, EventListener {
|
||||||
|
|
||||||
|
|
||||||
|
private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||||
|
onReceivedBroadcast(intent, intent.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
private View mContentView;
|
private View mContentView;
|
||||||
private SharedPreferences mPreferences;
|
private SharedPreferences mPreferences;
|
||||||
|
private View mProgressContainer;
|
||||||
|
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
|
private RecyclerView mRecyclerView;
|
||||||
|
private AbsStatusesAdapter<Data> mAdapter;
|
||||||
|
private SimpleDrawerCallback mDrawerCallback;
|
||||||
|
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||||
|
super.onScrollStateChanged(recyclerView, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||||
|
if (isRefreshing()) return;
|
||||||
|
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
||||||
|
onLoadMoreStatuses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canScroll(float dy) {
|
||||||
|
return mDrawerCallback.canScroll(dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTouch() {
|
||||||
|
mDrawerCallback.cancelTouch();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fling(float velocity) {
|
public void fling(float velocity) {
|
||||||
mDrawerCallback.fling(velocity);
|
mDrawerCallback.fling(velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds);
|
@Override
|
||||||
|
public boolean isScrollContent(float x, float y) {
|
||||||
|
return mDrawerCallback.isScrollContent(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scrollBy(float dy) {
|
public void scrollBy(float dy) {
|
||||||
|
@ -51,51 +103,34 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment
|
||||||
return mDrawerCallback.shouldLayoutHeaderBottom();
|
return mDrawerCallback.shouldLayoutHeaderBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canScroll(float dy) {
|
|
||||||
return mDrawerCallback.canScroll(dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isScrollContent(float x, float y) {
|
|
||||||
return mDrawerCallback.isScrollContent(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelTouch() {
|
|
||||||
mDrawerCallback.cancelTouch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void topChanged(int offset) {
|
public void topChanged(int offset) {
|
||||||
mDrawerCallback.topChanged(offset);
|
mDrawerCallback.topChanged(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private View mProgressContainer;
|
public AbsStatusesAdapter<Data> getAdapter() {
|
||||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
return mAdapter;
|
||||||
private RecyclerView mRecyclerView;
|
}
|
||||||
|
|
||||||
private AbsStatusesAdapter<Data> mAdapter;
|
public SharedPreferences getSharedPreferences() {
|
||||||
|
if (mPreferences != null) return mPreferences;
|
||||||
|
return mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
private SimpleDrawerCallback mDrawerCallback;
|
public abstract int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds);
|
||||||
|
|
||||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
public boolean isRefreshing() {
|
||||||
@Override
|
return mSwipeRefreshLayout.isRefreshing();
|
||||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
}
|
||||||
super.onScrollStateChanged(recyclerView, newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public void setRefreshing(boolean refreshing) {
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
mSwipeRefreshLayout.setRefreshing(refreshing);
|
||||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
}
|
||||||
final LoaderManager lm = getLoaderManager();
|
|
||||||
if (lm.hasRunningLoaders()) return;
|
@Override
|
||||||
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
final long[] maxIds = new long[]{mAdapter.getStatus(mAdapter.getStatusCount() - 1).id};
|
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
||||||
getStatuses(null, maxIds, null);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
@ -116,17 +151,86 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment
|
||||||
}
|
}
|
||||||
mRecyclerView.setAdapter(mAdapter);
|
mRecyclerView.setAdapter(mAdapter);
|
||||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||||
|
mAdapter.setEventListener(this);
|
||||||
getLoaderManager().initLoader(0, getArguments(), this);
|
getLoaderManager().initLoader(0, getArguments(), this);
|
||||||
setListShown(false);
|
setListShown(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract AbsStatusesAdapter<Data> onCreateAdapter(Context context, boolean compact);
|
@Override
|
||||||
|
public void onStart() {
|
||||||
private void setListShown(boolean shown) {
|
super.onStart();
|
||||||
mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE);
|
final IntentFilter filter = new IntentFilter();
|
||||||
mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE);
|
onSetIntentFilter(filter);
|
||||||
|
registerReceiver(mStateReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
unregisterReceiver(mStateReceiver);
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(Loader<Data> loader, Data data) {
|
||||||
|
setRefreshing(false);
|
||||||
|
mAdapter.setData(data);
|
||||||
|
setListShown(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(Loader<Data> loader) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
triggerRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusActionClick(StatusViewHolder holder, int id, int position) {
|
||||||
|
switch (id) {
|
||||||
|
case R.id.reply_count: {
|
||||||
|
final Context context = getActivity();
|
||||||
|
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY);
|
||||||
|
intent.setPackage(context.getPackageName());
|
||||||
|
intent.putExtra(IntentConstants.EXTRA_STATUS, mAdapter.getStatus(position));
|
||||||
|
context.startActivity(intent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||||
|
Utils.openStatus(getActivity(), mAdapter.getStatus(position), null);
|
||||||
|
// final View cardView = holder.getCardView();
|
||||||
|
// if (cardView != null && context instanceof FragmentActivity) {
|
||||||
|
// final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
||||||
|
// new Pair<>(cardView, StatusFragment.TRANSITION_NAME_CARD));
|
||||||
|
// Utils.openStatus(context, getStatus(position), options);
|
||||||
|
// } else {
|
||||||
|
// Utils.openStatus(context, getStatus(position), null);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGapClick(GapViewHolder holder, int position) {
|
||||||
|
final ParcelableStatus status = mAdapter.getStatus(position);
|
||||||
|
final long sinceId = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(position + 1).id : -1;
|
||||||
|
final long[] accountIds = {status.account_id};
|
||||||
|
final long[] maxIds = {status.id};
|
||||||
|
final long[] sinceIds = {sinceId};
|
||||||
|
getStatuses(accountIds, maxIds, sinceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusMenuClick(StatusViewHolder holder, int position) {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putParcelable(EXTRA_STATUS, mAdapter.getStatus(position));
|
||||||
|
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
||||||
|
f.setArguments(args);
|
||||||
|
f.show(getActivity().getSupportFragmentManager(), "status_menu");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
@ -144,44 +248,36 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public boolean scrollToStart() {
|
||||||
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||||
|
final int tabPosition = getTabPosition();
|
||||||
|
if (twitter != null && tabPosition != -1) {
|
||||||
|
twitter.clearUnreadCountAsync(tabPosition);
|
||||||
|
}
|
||||||
|
mRecyclerView.smoothScrollToPosition(0);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract long[] getAccountIds();
|
||||||
|
|
||||||
protected Data getAdapterData() {
|
protected Data getAdapterData() {
|
||||||
return mAdapter.getData();
|
return mAdapter.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRefreshing(boolean refreshing) {
|
protected void setAdapterData(Data data) {
|
||||||
mSwipeRefreshLayout.setRefreshing(refreshing);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(Loader<Data> loader, Data data) {
|
|
||||||
setRefreshing(false);
|
|
||||||
mAdapter.setData(data);
|
mAdapter.setData(data);
|
||||||
setListShown(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected abstract AbsStatusesAdapter<Data> onCreateAdapter(Context context, boolean compact);
|
||||||
public void onLoaderReset(Loader<Data> loader) {
|
|
||||||
|
protected abstract void onLoadMoreStatuses();
|
||||||
|
|
||||||
|
protected abstract void onReceivedBroadcast(Intent intent, String action);
|
||||||
|
|
||||||
|
protected abstract void onSetIntentFilter(IntentFilter filter);
|
||||||
|
|
||||||
|
private void setListShown(boolean shown) {
|
||||||
|
mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||||
|
mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRefresh() {
|
|
||||||
if (mAdapter.getStatusCount() > 0) {
|
|
||||||
final long[] sinceIds = new long[]{mAdapter.getStatus(0).id};
|
|
||||||
getStatuses(null, null, sinceIds);
|
|
||||||
} else {
|
|
||||||
getStatuses(null, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SharedPreferences getSharedPreferences() {
|
|
||||||
if (mPreferences != null) return mPreferences;
|
|
||||||
return mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.PorterDuff.Mode;
|
import android.graphics.PorterDuff.Mode;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -54,20 +55,24 @@ import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.commonsware.cwac.merge.MergeAdapter;
|
import com.commonsware.cwac.merge.MergeAdapter;
|
||||||
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
|
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.FiltersActivity;
|
import org.mariotaku.twidere.activity.FiltersActivity;
|
||||||
import org.mariotaku.twidere.activity.SettingsActivity;
|
import org.mariotaku.twidere.activity.SettingsActivity;
|
||||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||||
import org.mariotaku.twidere.activity.support.AccountsManagerActivity;
|
import org.mariotaku.twidere.activity.support.AccountsManagerActivity;
|
||||||
|
import org.mariotaku.twidere.activity.support.ComposeActivity;
|
||||||
import org.mariotaku.twidere.activity.support.DraftsActivity;
|
import org.mariotaku.twidere.activity.support.DraftsActivity;
|
||||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||||
import org.mariotaku.twidere.activity.support.UserProfileEditorActivity;
|
import org.mariotaku.twidere.activity.support.UserProfileEditorActivity;
|
||||||
import org.mariotaku.twidere.adapter.ArrayAdapter;
|
import org.mariotaku.twidere.adapter.ArrayAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.Account.Indices;
|
import org.mariotaku.twidere.model.ParcelableAccount.Indices;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
|
import org.mariotaku.twidere.util.CompareUtils;
|
||||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||||
import org.mariotaku.twidere.util.ThemeUtils;
|
import org.mariotaku.twidere.util.ThemeUtils;
|
||||||
import org.mariotaku.twidere.util.Utils;
|
import org.mariotaku.twidere.util.Utils;
|
||||||
|
@ -76,13 +81,11 @@ import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import static org.mariotaku.twidere.util.Utils.openUserFavorites;
|
import static org.mariotaku.twidere.util.Utils.openUserFavorites;
|
||||||
import static org.mariotaku.twidere.util.Utils.openUserListMemberships;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.openUserLists;
|
import static org.mariotaku.twidere.util.Utils.openUserLists;
|
||||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||||
import static org.mariotaku.twidere.util.Utils.openUserTimeline;
|
|
||||||
|
|
||||||
public class AccountsDashboardFragment extends BaseSupportListFragment implements LoaderCallbacks<Cursor>,
|
public class AccountsDashboardFragment extends BaseSupportListFragment implements LoaderCallbacks<Cursor>,
|
||||||
OnSharedPreferenceChangeListener, OnCheckedChangeListener {
|
OnSharedPreferenceChangeListener, OnCheckedChangeListener, ImageLoadingListener, OnClickListener {
|
||||||
|
|
||||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
||||||
this, 0, this);
|
this, 0, this);
|
||||||
|
@ -106,48 +109,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
private Context mThemedContext;
|
private Context mThemedContext;
|
||||||
private ImageLoaderWrapper mImageLoader;
|
private ImageLoaderWrapper mImageLoader;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
|
||||||
mResolver = getContentResolver();
|
|
||||||
final Context context = getView().getContext();
|
|
||||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
|
||||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
|
||||||
final ListView listView = getListView();
|
|
||||||
mAdapter = new MergeAdapter();
|
|
||||||
mAccountsAdapter = new AccountSelectorAdapter(context, this);
|
|
||||||
mAccountOptionsAdapter = new AccountOptionsAdapter(context);
|
|
||||||
mAppMenuAdapter = new AppMenuAdapter(context);
|
|
||||||
mAppMenuSectionView = newSectionView(context, R.string.more);
|
|
||||||
mAccountSelectorView = inflater.inflate(R.layout.header_drawer_account_selector, listView, false);
|
|
||||||
mAccountsSelector = (RecyclerView) mAccountSelectorView.findViewById(R.id.other_accounts_list);
|
|
||||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
|
|
||||||
layoutManager.setStackFromEnd(true);
|
|
||||||
mAccountsSelector.setLayoutManager(layoutManager);
|
|
||||||
mAccountsSelector.setAdapter(mAccountsAdapter);
|
|
||||||
mAccountProfileContainer = mAccountSelectorView.findViewById(R.id.profile_container);
|
|
||||||
mAccountProfileImageView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_image);
|
|
||||||
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.account_profile_banner);
|
|
||||||
mAccountProfileNameView = (TextView) mAccountSelectorView.findViewById(R.id.name);
|
|
||||||
mAccountProfileScreenNameView = (TextView) mAccountSelectorView.findViewById(R.id.screen_name);
|
|
||||||
mAccountsToggle = (Switch) mAccountSelectorView.findViewById(R.id.toggle);
|
|
||||||
mAccountsToggle.setOnCheckedChangeListener(this);
|
|
||||||
mAdapter.addView(mAccountSelectorView, false);
|
|
||||||
mAdapter.addAdapter(mAccountOptionsAdapter);
|
|
||||||
mAdapter.addView(mAppMenuSectionView, false);
|
|
||||||
mAdapter.addAdapter(mAppMenuAdapter);
|
|
||||||
setListAdapter(mAdapter);
|
|
||||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
|
||||||
getLoaderManager().initLoader(0, null, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void fitSystemWindows(Rect insets) {
|
|
||||||
// No-op
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
|
@ -163,14 +124,57 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
updateDefaultAccountState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
final ParcelableAccount account = mAccountsAdapter.getSelectedAccount();
|
||||||
|
if (account == null) return;
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put(Accounts.IS_ACTIVATED, isChecked);
|
||||||
|
final String where = Accounts.ACCOUNT_ID + " = " + account.account_id;
|
||||||
|
mResolver.update(Accounts.CONTENT_URI, values, where, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.profile_container: {
|
||||||
|
final ParcelableAccount account = mAccountsAdapter.getSelectedAccount();
|
||||||
|
if (account == null) return;
|
||||||
|
final FragmentActivity activity = getActivity();
|
||||||
|
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
|
||||||
|
new Pair<View, String>(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
||||||
|
openUserProfile(activity, account.account_id, account.account_id,
|
||||||
|
account.screen_name, activityOption);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||||
return new CursorLoader(getActivity(), Accounts.CONTENT_URI, Accounts.COLUMNS, null, null, Accounts.SORT_POSITION);
|
return new CursorLoader(getActivity(), Accounts.CONTENT_URI, Accounts.COLUMNS, null, null, Accounts.SORT_POSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
|
||||||
return LayoutInflater.from(getThemedContext()).inflate(R.layout.fragment_accounts_drawer, container, false);
|
if (data != null && data.getCount() > 0 && mAccountsAdapter.getSelectedAccountId() <= 0) {
|
||||||
|
data.moveToFirst();
|
||||||
|
mAccountsAdapter.setSelectedAccountId(data.getLong(data.getColumnIndex(Accounts.ACCOUNT_ID)));
|
||||||
|
}
|
||||||
|
mAccountsAdapter.changeCursor(data);
|
||||||
|
updateAccountOptionsSeparatorLabel();
|
||||||
|
updateDefaultAccountState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(final Loader<Cursor> loader) {
|
||||||
|
mAccountsAdapter.changeCursor(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -178,18 +182,10 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
final ListAdapter adapter = mAdapter.getAdapter(position);
|
final ListAdapter adapter = mAdapter.getAdapter(position);
|
||||||
final Object item = mAdapter.getItem(position);
|
final Object item = mAdapter.getItem(position);
|
||||||
if (adapter instanceof AccountOptionsAdapter) {
|
if (adapter instanceof AccountOptionsAdapter) {
|
||||||
final Account account = mAccountsAdapter.getSelectedAccount();
|
final ParcelableAccount account = mAccountsAdapter.getSelectedAccount();
|
||||||
if (account == null || !(item instanceof OptionItem)) return;
|
if (account == null || !(item instanceof OptionItem)) return;
|
||||||
final OptionItem option = (OptionItem) item;
|
final OptionItem option = (OptionItem) item;
|
||||||
switch (option.id) {
|
switch (option.id) {
|
||||||
case MENU_VIEW_PROFILE: {
|
|
||||||
final FragmentActivity activity = getActivity();
|
|
||||||
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
|
|
||||||
new Pair<View, String>(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
|
||||||
openUserProfile(activity, account.account_id, account.account_id,
|
|
||||||
account.screen_name, activityOption);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_SEARCH: {
|
case MENU_SEARCH: {
|
||||||
final FragmentActivity a = getActivity();
|
final FragmentActivity a = getActivity();
|
||||||
if (a instanceof HomeActivity) {
|
if (a instanceof HomeActivity) {
|
||||||
|
@ -200,8 +196,11 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
closeAccountsDrawer();
|
closeAccountsDrawer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MENU_STATUSES: {
|
case MENU_COMPOSE: {
|
||||||
openUserTimeline(getActivity(), account.account_id, account.account_id, account.screen_name);
|
final Intent composeIntent = new Intent(INTENT_ACTION_COMPOSE);
|
||||||
|
composeIntent.setClass(getActivity(), ComposeActivity.class);
|
||||||
|
composeIntent.putExtra(EXTRA_ACCOUNT_IDS, new long[]{account.account_id});
|
||||||
|
startActivity(composeIntent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MENU_FAVORITES: {
|
case MENU_FAVORITES: {
|
||||||
|
@ -212,10 +211,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name);
|
openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MENU_LIST_MEMBERSHIPS: {
|
|
||||||
openUserListMemberships(getActivity(), account.account_id, account.account_id, account.screen_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_EDIT: {
|
case MENU_EDIT: {
|
||||||
final Bundle bundle = new Bundle();
|
final Bundle bundle = new Bundle();
|
||||||
bundle.putLong(EXTRA_ACCOUNT_ID, account.account_id);
|
bundle.putLong(EXTRA_ACCOUNT_ID, account.account_id);
|
||||||
|
@ -259,25 +254,23 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(final Loader<Cursor> loader) {
|
public void onLoadingStarted(String imageUri, View view) {
|
||||||
mAccountsAdapter.changeCursor(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
if (data != null && data.getCount() > 0 && mAccountsAdapter.getSelectedAccountId() <= 0) {
|
|
||||||
data.moveToFirst();
|
|
||||||
mAccountsAdapter.setSelectedAccountId(data.getLong(data.getColumnIndex(Accounts.ACCOUNT_ID)));
|
|
||||||
}
|
|
||||||
mAccountsAdapter.changeCursor(data);
|
|
||||||
updateAccountOptionsSeparatorLabel();
|
|
||||||
updateDefaultAccountState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||||
super.onResume();
|
view.setTag(imageUri);
|
||||||
updateDefaultAccountState();
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadingCancelled(String imageUri, View view) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,6 +280,59 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStatusBarHeight(int height) {
|
||||||
|
mAccountProfileContainer.setPadding(0, height, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fitSystemWindows(Rect insets) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||||
|
mResolver = getContentResolver();
|
||||||
|
final Context context = getView().getContext();
|
||||||
|
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||||
|
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||||
|
final ListView listView = getListView();
|
||||||
|
mAdapter = new MergeAdapter();
|
||||||
|
mAccountsAdapter = new AccountSelectorAdapter(context, this);
|
||||||
|
mAccountOptionsAdapter = new AccountOptionsAdapter(context);
|
||||||
|
mAppMenuAdapter = new AppMenuAdapter(context);
|
||||||
|
mAppMenuSectionView = newSectionView(context, R.string.more);
|
||||||
|
mAccountSelectorView = inflater.inflate(R.layout.header_drawer_account_selector, listView, false);
|
||||||
|
mAccountsSelector = (RecyclerView) mAccountSelectorView.findViewById(R.id.other_accounts_list);
|
||||||
|
final LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
|
||||||
|
layoutManager.setStackFromEnd(true);
|
||||||
|
mAccountsSelector.setLayoutManager(layoutManager);
|
||||||
|
mAccountsSelector.setAdapter(mAccountsAdapter);
|
||||||
|
mAccountProfileContainer = mAccountSelectorView.findViewById(R.id.profile_container);
|
||||||
|
mAccountProfileImageView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_image);
|
||||||
|
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.account_profile_banner);
|
||||||
|
mAccountProfileNameView = (TextView) mAccountSelectorView.findViewById(R.id.name);
|
||||||
|
mAccountProfileScreenNameView = (TextView) mAccountSelectorView.findViewById(R.id.screen_name);
|
||||||
|
mAccountsToggle = (Switch) mAccountSelectorView.findViewById(R.id.toggle);
|
||||||
|
|
||||||
|
mAccountProfileContainer.setOnClickListener(this);
|
||||||
|
|
||||||
|
mAccountsToggle.setOnCheckedChangeListener(this);
|
||||||
|
mAdapter.addView(mAccountSelectorView, false);
|
||||||
|
mAdapter.addAdapter(mAccountOptionsAdapter);
|
||||||
|
mAdapter.addView(mAppMenuSectionView, false);
|
||||||
|
mAdapter.addAdapter(mAppMenuAdapter);
|
||||||
|
setListAdapter(mAdapter);
|
||||||
|
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
|
getLoaderManager().initLoader(0, null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||||
|
return LayoutInflater.from(getThemedContext()).inflate(R.layout.fragment_accounts_drawer, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
@ -316,8 +362,21 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
return mThemedContext = new ContextThemeWrapper(context, themeResource);
|
return mThemedContext = new ContextThemeWrapper(context, themeResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TextView newSectionView(final Context context, final int titleRes) {
|
||||||
|
final TextView textView = new TextView(context, null, android.R.attr.listSeparatorTextViewStyle);
|
||||||
|
if (titleRes != 0) {
|
||||||
|
textView.setText(titleRes);
|
||||||
|
}
|
||||||
|
return textView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAccountSelected(ParcelableAccount account) {
|
||||||
|
mAccountsAdapter.setSelectedAccountId(account.account_id);
|
||||||
|
updateAccountOptionsSeparatorLabel();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateAccountOptionsSeparatorLabel() {
|
private void updateAccountOptionsSeparatorLabel() {
|
||||||
final Account account = mAccountsAdapter.getSelectedAccount();
|
final ParcelableAccount account = mAccountsAdapter.getSelectedAccount();
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -329,43 +388,23 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
final Resources res = getResources();
|
final Resources res = getResources();
|
||||||
final int defWidth = res.getDisplayMetrics().widthPixels;
|
final int defWidth = res.getDisplayMetrics().widthPixels;
|
||||||
final int width = bannerWidth > 0 ? bannerWidth : defWidth;
|
final int width = bannerWidth > 0 ? bannerWidth : defWidth;
|
||||||
mImageLoader.displayProfileBanner(mAccountProfileBannerView, account.profile_banner_url, width);
|
final String bannerUrl = Utils.getBestBannerUrl(account.profile_banner_url, width);
|
||||||
|
final ImageView bannerView = mAccountProfileBannerView;
|
||||||
|
if (bannerView.getDrawable() == null || !CompareUtils.objectEquals(bannerUrl, bannerView.getTag())) {
|
||||||
|
mImageLoader.displayProfileBanner(mAccountProfileBannerView, bannerUrl, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDefaultAccountState() {
|
private void updateDefaultAccountState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextView newSectionView(final Context context, final int titleRes) {
|
|
||||||
final TextView textView = new TextView(context, null, android.R.attr.listSeparatorTextViewStyle);
|
|
||||||
if (titleRes != 0) {
|
|
||||||
textView.setText(titleRes);
|
|
||||||
}
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
final Account account = mAccountsAdapter.getSelectedAccount();
|
|
||||||
if (account == null) return;
|
|
||||||
final ContentValues values = new ContentValues();
|
|
||||||
values.put(Accounts.IS_ACTIVATED, isChecked);
|
|
||||||
final String where = Accounts.ACCOUNT_ID + " = " + account.account_id;
|
|
||||||
mResolver.update(Accounts.CONTENT_URI, values, where, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusBarHeight(int height) {
|
|
||||||
mAccountProfileContainer.setPadding(0, height, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static final class AccountOptionsAdapter extends OptionItemsAdapter {
|
private static final class AccountOptionsAdapter extends OptionItemsAdapter {
|
||||||
|
|
||||||
private static final ArrayList<OptionItem> sOptions = new ArrayList<>();
|
private static final ArrayList<OptionItem> sOptions = new ArrayList<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
sOptions.add(new OptionItem(R.string.profile, R.drawable.ic_action_profile, MENU_VIEW_PROFILE));
|
|
||||||
sOptions.add(new OptionItem(android.R.string.search_go, R.drawable.ic_action_search, MENU_SEARCH));
|
sOptions.add(new OptionItem(android.R.string.search_go, R.drawable.ic_action_search, MENU_SEARCH));
|
||||||
sOptions.add(new OptionItem(R.string.statuses, R.drawable.ic_action_quote, MENU_STATUSES));
|
sOptions.add(new OptionItem(R.string.compose, R.drawable.ic_action_status_compose, MENU_COMPOSE));
|
||||||
sOptions.add(new OptionItem(R.string.favorites, R.drawable.ic_action_star, MENU_FAVORITES));
|
sOptions.add(new OptionItem(R.string.favorites, R.drawable.ic_action_star, MENU_FAVORITES));
|
||||||
sOptions.add(new OptionItem(R.string.lists, R.drawable.ic_action_list, MENU_LISTS));
|
sOptions.add(new OptionItem(R.string.lists, R.drawable.ic_action_list, MENU_LISTS));
|
||||||
}
|
}
|
||||||
|
@ -423,6 +462,36 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeCursor(Cursor cursor) {
|
||||||
|
mCursor = cursor;
|
||||||
|
if (cursor != null) {
|
||||||
|
mIndices = new Indices(cursor);
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParcelableAccount getSelectedAccount() {
|
||||||
|
final Cursor c = mCursor;
|
||||||
|
final Indices i = mIndices;
|
||||||
|
if (c != null && i != null && c.moveToFirst()) {
|
||||||
|
while (!c.isAfterLast()) {
|
||||||
|
if (c.getLong(mIndices.account_id) == mSelectedAccountId)
|
||||||
|
return new ParcelableAccount(c, mIndices);
|
||||||
|
c.moveToNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSelectedAccountId() {
|
||||||
|
return mSelectedAccountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedAccountId(long accountId) {
|
||||||
|
mSelectedAccountId = accountId;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccountProfileImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public AccountProfileImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
final View view = mInflater.inflate(R.layout.adapter_item_compose_account, parent, false);
|
final View view = mInflater.inflate(R.layout.adapter_item_compose_account, parent, false);
|
||||||
|
@ -446,50 +515,15 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||||
return Math.max(mCursor.getCount() - 1, 0);
|
return Math.max(mCursor.getCount() - 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeCursor(Cursor cursor) {
|
|
||||||
mCursor = cursor;
|
|
||||||
if (cursor != null) {
|
|
||||||
mIndices = new Indices(cursor);
|
|
||||||
}
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedAccountId(long accountId) {
|
|
||||||
mSelectedAccountId = accountId;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Account getSelectedAccount() {
|
|
||||||
final Cursor c = mCursor;
|
|
||||||
final Indices i = mIndices;
|
|
||||||
if (c != null && i != null && c.moveToFirst()) {
|
|
||||||
while (!c.isAfterLast()) {
|
|
||||||
if (c.getLong(mIndices.account_id) == mSelectedAccountId)
|
|
||||||
return new Account(c, mIndices);
|
|
||||||
c.moveToNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSelectedAccountId() {
|
|
||||||
return mSelectedAccountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispatchItemSelected(int position) {
|
private void dispatchItemSelected(int position) {
|
||||||
final Cursor c = mCursor;
|
final Cursor c = mCursor;
|
||||||
c.moveToPosition(position);
|
c.moveToPosition(position);
|
||||||
if (c.getLong(mIndices.account_id) != mSelectedAccountId || c.moveToNext()) {
|
if (c.getLong(mIndices.account_id) != mSelectedAccountId || c.moveToNext()) {
|
||||||
mFragment.onAccountSelected(new Account(c, mIndices));
|
mFragment.onAccountSelected(new ParcelableAccount(c, mIndices));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAccountSelected(Account account) {
|
|
||||||
mAccountsAdapter.setSelectedAccountId(account.account_id);
|
|
||||||
updateAccountOptionsSeparatorLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class OptionItem {
|
private static class OptionItem {
|
||||||
|
|
||||||
private final int name, icon, id;
|
private final int name, icon, id;
|
||||||
|
|
|
@ -35,12 +35,12 @@ import android.widget.ListView;
|
||||||
import com.mobeta.android.dslv.DragSortListView;
|
import com.mobeta.android.dslv.DragSortListView;
|
||||||
import com.mobeta.android.dslv.DragSortListView.DropListener;
|
import com.mobeta.android.dslv.DragSortListView.DropListener;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Where;
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||||
import org.mariotaku.twidere.activity.support.SignInActivity;
|
import org.mariotaku.twidere.activity.support.SignInActivity;
|
||||||
import org.mariotaku.twidere.adapter.AccountsAdapter;
|
import org.mariotaku.twidere.adapter.AccountsAdapter;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.DirectMessages;
|
import org.mariotaku.twidere.provider.TweetStore.DirectMessages;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Inbox;
|
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Inbox;
|
||||||
|
@ -61,7 +61,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements
|
||||||
|
|
||||||
private AccountsAdapter mAdapter;
|
private AccountsAdapter mAdapter;
|
||||||
private SharedPreferences mPreferences;
|
private SharedPreferences mPreferences;
|
||||||
private Account mSelectedAccount;
|
private ParcelableAccount mSelectedAccount;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
@ -178,7 +178,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||||
if (!(menuInfo instanceof AdapterContextMenuInfo)) return;
|
if (!(menuInfo instanceof AdapterContextMenuInfo)) return;
|
||||||
final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
||||||
final Account account = mAdapter.getAccount(info.position);
|
final ParcelableAccount account = mAdapter.getAccount(info.position);
|
||||||
menu.setHeaderTitle(account.name);
|
menu.setHeaderTitle(account.name);
|
||||||
final MenuInflater inflater = new MenuInflater(v.getContext());
|
final MenuInflater inflater = new MenuInflater(v.getContext());
|
||||||
inflater.inflate(R.menu.action_manager_account, menu);
|
inflater.inflate(R.menu.action_manager_account, menu);
|
||||||
|
@ -258,7 +258,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements
|
||||||
final long id = c.getLong(idIdx);
|
final long id = c.getLong(idIdx);
|
||||||
final ContentValues values = new ContentValues();
|
final ContentValues values = new ContentValues();
|
||||||
values.put(Accounts.SORT_POSITION, i);
|
values.put(Accounts.SORT_POSITION, i);
|
||||||
final Where where = Where.equals(Accounts._ID, id);
|
final Expression where = Expression.equals(Accounts._ID, id);
|
||||||
cr.update(Accounts.CONTENT_URI, values, where.getSQL(), null);
|
cr.update(Accounts.CONTENT_URI, values, where.getSQL(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,211 +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.support;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.mariotaku.refreshnow.widget.OnRefreshListener;
|
|
||||||
import org.mariotaku.refreshnow.widget.RefreshMode;
|
|
||||||
import org.mariotaku.refreshnow.widget.RefreshNowConfig;
|
|
||||||
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator;
|
|
||||||
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator.IndicatorConfig;
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
|
|
||||||
import org.mariotaku.twidere.util.ThemeUtils;
|
|
||||||
import org.mariotaku.twidere.view.RefreshNowStaggeredGridView;
|
|
||||||
|
|
||||||
public abstract class BasePullToRefreshStaggeredGridFragment extends BaseSupportStaggeredGridFragment implements
|
|
||||||
IBasePullToRefreshFragment, OnTouchListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RefreshNowStaggeredGridView getListView() {
|
|
||||||
return (RefreshNowStaggeredGridView) super.getListView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RefreshMode getRefreshMode() {
|
|
||||||
if (getView() == null) return RefreshMode.NONE;
|
|
||||||
return getListView().getRefreshMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRefreshing() {
|
|
||||||
if (getView() == null) return false;
|
|
||||||
return getListView().isRefreshing();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide default implementation to return a simple list view. Subclasses
|
|
||||||
* can override to replace with their own layout. If doing so, the returned
|
|
||||||
* view hierarchy <em>must</em> have a ListView whose id is
|
|
||||||
* {@link android.R.id#list android.R.id.list} and can optionally have a
|
|
||||||
* sibling view id {@link android.R.id#empty android.R.id.empty} that is to
|
|
||||||
* be shown when the list is empty.
|
|
||||||
* <p>
|
|
||||||
* If you are overriding this method with your own custom content, consider
|
|
||||||
* including the standard layout {@link android.R.layout#list_content} in
|
|
||||||
* your layout file, so that you continue to retain all of the standard
|
|
||||||
* behavior of ListFragment. In particular, this is currently the only way
|
|
||||||
* to have the built-in indeterminant progress state be shown.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
|
||||||
final Context context = getActivity();
|
|
||||||
|
|
||||||
final FrameLayout root = new FrameLayout(context);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
final LinearLayout pframe = new LinearLayout(context);
|
|
||||||
pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
|
|
||||||
pframe.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
pframe.setVisibility(View.GONE);
|
|
||||||
pframe.setGravity(Gravity.CENTER);
|
|
||||||
|
|
||||||
final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
|
|
||||||
pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
final FrameLayout lframe = new FrameLayout(context);
|
|
||||||
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
|
|
||||||
|
|
||||||
final TextView tv = new TextView(getActivity());
|
|
||||||
tv.setId(INTERNAL_EMPTY_ID);
|
|
||||||
tv.setGravity(Gravity.CENTER);
|
|
||||||
lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
final RefreshNowStaggeredGridView lv = (RefreshNowStaggeredGridView) inflater.inflate(
|
|
||||||
R.layout.refreshnow_staggered_gridview, lframe, false);
|
|
||||||
lv.setId(android.R.id.list);
|
|
||||||
lv.setDrawSelectorOnTop(false);
|
|
||||||
lv.setOnRefreshListener(this);
|
|
||||||
lv.setOnTouchListener(this);
|
|
||||||
lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
final RefreshNowProgressIndicator indicator = new RefreshNowProgressIndicator(context);
|
|
||||||
final IndicatorConfig config = ThemeUtils.buildRefreshIndicatorConfig(context);
|
|
||||||
indicator.setConfig(config);
|
|
||||||
final int indicatorHeight = Math.round(3 * getResources().getDisplayMetrics().density);
|
|
||||||
lframe.addView(indicator, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, indicatorHeight,
|
|
||||||
Gravity.TOP));
|
|
||||||
|
|
||||||
lv.setRefreshIndicatorView(indicator);
|
|
||||||
|
|
||||||
root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRefreshComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onRefreshStart(final RefreshMode mode) {
|
|
||||||
if (mode.hasStart()) {
|
|
||||||
onRefreshFromStart();
|
|
||||||
} else if (mode.hasEnd()) {
|
|
||||||
onRefreshFromEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean onTouch(final View v, final MotionEvent event) {
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case MotionEvent.ACTION_DOWN: {
|
|
||||||
onListTouched();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setConfig(final RefreshNowConfig config) {
|
|
||||||
if (getView() == null) return;
|
|
||||||
getListView().setConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOnRefreshListener(final OnRefreshListener listener) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRefreshComplete() {
|
|
||||||
if (getView() == null) return;
|
|
||||||
getListView().setRefreshComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRefreshIndicatorView(final View view) {
|
|
||||||
if (getView() == null) return;
|
|
||||||
getListView().setRefreshIndicatorView(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRefreshing(final boolean refresh) {
|
|
||||||
if (getView() == null) return;
|
|
||||||
getListView().setRefreshing(refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRefreshMode(final RefreshMode mode) {
|
|
||||||
if (getView() == null) return;
|
|
||||||
getListView().setRefreshMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean triggerRefresh() {
|
|
||||||
onRefreshFromStart();
|
|
||||||
setRefreshing(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onListTouched() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -40,8 +40,8 @@ import android.widget.ListView;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.Account.AccountWithCredentials;
|
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
import org.mariotaku.twidere.task.AsyncTask;
|
||||||
import org.mariotaku.twidere.util.AsyncTaskManager;
|
import org.mariotaku.twidere.util.AsyncTaskManager;
|
||||||
|
@ -345,9 +345,9 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MENU_TRANSLATE: {
|
case MENU_TRANSLATE: {
|
||||||
final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(),
|
final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(),
|
||||||
status.account_id);
|
status.account_id);
|
||||||
if (AccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
||||||
StatusTranslateDialogFragment.show(getFragmentManager(), status);
|
StatusTranslateDialogFragment.show(getFragmentManager(), status);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -1,578 +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.support;
|
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.MenuItem.OnMenuItemClickListener;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.AdapterView.OnItemLongClickListener;
|
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
import com.etsy.android.grid.StaggeredGridView;
|
|
||||||
|
|
||||||
import org.mariotaku.menucomponent.widget.PopupMenu;
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTaskManager;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.ClipboardUtils;
|
|
||||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
|
||||||
import org.mariotaku.twidere.util.PositionManager;
|
|
||||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.Utils;
|
|
||||||
import org.mariotaku.twidere.util.collection.NoDuplicatesCopyOnWriteArrayList;
|
|
||||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.mariotaku.twidere.util.Utils.cancelRetweet;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.clearListViewChoices;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.setMenuForStatus;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
|
||||||
|
|
||||||
abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefreshStaggeredGridFragment implements
|
|
||||||
LoaderCallbacks<Data>, OnItemLongClickListener, OnMenuItemClickListener,
|
|
||||||
MultiSelectManager.Callback, MenuButtonClickListener {
|
|
||||||
|
|
||||||
private AsyncTaskManager mAsyncTaskManager;
|
|
||||||
private SharedPreferences mPreferences;
|
|
||||||
|
|
||||||
private StaggeredGridView mListView;
|
|
||||||
private IStatusesListAdapter<Data> mAdapter;
|
|
||||||
private PopupMenu mPopupMenu;
|
|
||||||
|
|
||||||
private Data mData;
|
|
||||||
private ParcelableStatus mSelectedStatus;
|
|
||||||
|
|
||||||
private boolean mLoadMoreAutomatically;
|
|
||||||
private int mListScrollOffset;
|
|
||||||
|
|
||||||
private MultiSelectManager mMultiSelectManager;
|
|
||||||
private PositionManager mPositionManager;
|
|
||||||
|
|
||||||
private int mFirstVisibleItem;
|
|
||||||
private int mSelectedPosition;
|
|
||||||
|
|
||||||
private final Map<Long, Set<Long>> mUnreadCountsToRemove = Collections
|
|
||||||
.synchronizedMap(new HashMap<Long, Set<Long>>());
|
|
||||||
private final List<Integer> mReadPositions = new NoDuplicatesCopyOnWriteArrayList<Integer>();
|
|
||||||
|
|
||||||
private RemoveUnreadCountsTask<Data> mRemoveUnreadCountsTask;
|
|
||||||
|
|
||||||
public AsyncTaskManager getAsyncTaskManager() {
|
|
||||||
return mAsyncTaskManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Data getData() {
|
|
||||||
return mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IStatusesListAdapter<Data> getListAdapter() {
|
|
||||||
return mAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParcelableStatus getSelectedStatus() {
|
|
||||||
return mSelectedStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SharedPreferences getSharedPreferences() {
|
|
||||||
return mPreferences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract int getStatuses(long[] account_ids, long[] max_ids, long[] since_ids);
|
|
||||||
|
|
||||||
public final Map<Long, Set<Long>> getUnreadCountsToRemove() {
|
|
||||||
return mUnreadCountsToRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
mAsyncTaskManager = getAsyncTaskManager();
|
|
||||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
|
||||||
mPositionManager = new PositionManager(getActivity());
|
|
||||||
mMultiSelectManager = getMultiSelectManager();
|
|
||||||
mListView = getListView();
|
|
||||||
mAdapter = newAdapterInstance();
|
|
||||||
mAdapter.setMenuButtonClickListener(this);
|
|
||||||
setListAdapter(null);
|
|
||||||
setListHeaderFooters(mListView);
|
|
||||||
setListAdapter(mAdapter);
|
|
||||||
mListView.setSelector(android.R.color.transparent);
|
|
||||||
mListView.setOnItemLongClickListener(this);
|
|
||||||
setListShown(false);
|
|
||||||
getLoaderManager().initLoader(0, getArguments(), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract Loader<Data> onCreateLoader(int id, Bundle args);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
|
|
||||||
final Object tag = view.getTag();
|
|
||||||
if (tag instanceof StatusListViewHolder) {
|
|
||||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
|
||||||
final ParcelableStatus status = mAdapter.getStatus(position - mListView.getHeaderViewsCount());
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
|
||||||
}
|
|
||||||
if (holder.show_as_gap) return false;
|
|
||||||
if (mPreferences.getBoolean(KEY_LONG_CLICK_TO_OPEN_MENU, false)) {
|
|
||||||
openMenu(holder.content.getFakeOverflowButton(), status, position);
|
|
||||||
} else {
|
|
||||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemsCleared() {
|
|
||||||
clearListViewChoices(mListView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(final Object item) {
|
|
||||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemUnselected(final Object item) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onListItemClick(final StaggeredGridView l, final View v, final int position, final long id) {
|
|
||||||
final Object tag = v.getTag();
|
|
||||||
if (tag instanceof StatusListViewHolder) {
|
|
||||||
final int pos = position - l.getHeaderViewsCount();
|
|
||||||
final ParcelableStatus status = mAdapter.getStatus(pos);
|
|
||||||
if (status == null) return;
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
|
||||||
}
|
|
||||||
if (((StatusListViewHolder) tag).show_as_gap) {
|
|
||||||
final long since_id = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
|
||||||
getStatuses(new long[]{status.account_id}, new long[]{status.id}, new long[]{since_id});
|
|
||||||
mListView.setItemChecked(position, false);
|
|
||||||
} else {
|
|
||||||
if (mMultiSelectManager.isActive()) {
|
|
||||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
openStatus(getActivity(), status, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onLoaderReset(final Loader<Data> loader) {
|
|
||||||
mAdapter.setData(mData = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void onLoadFinished(final Loader<Data> loader, final Data data) {
|
|
||||||
if (getActivity() == null || getView() == null) return;
|
|
||||||
setListShown(true);
|
|
||||||
setRefreshComplete();
|
|
||||||
setProgressBarIndeterminateVisibility(false);
|
|
||||||
setData(data);
|
|
||||||
mFirstVisibleItem = -1;
|
|
||||||
mReadPositions.clear();
|
|
||||||
final int listVisiblePosition, savedChildIndex;
|
|
||||||
final boolean rememberPosition = mPreferences.getBoolean(KEY_REMEMBER_POSITION, true);
|
|
||||||
if (rememberPosition) {
|
|
||||||
listVisiblePosition = mListView.getLastVisiblePosition();
|
|
||||||
final int childCount = mListView.getChildCount();
|
|
||||||
savedChildIndex = childCount - 1;
|
|
||||||
if (childCount > 0) {
|
|
||||||
final View lastChild = mListView.getChildAt(savedChildIndex);
|
|
||||||
mListScrollOffset = lastChild != null ? lastChild.getTop() : 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
listVisiblePosition = mListView.getFirstVisiblePosition();
|
|
||||||
savedChildIndex = 0;
|
|
||||||
if (mListView.getChildCount() > 0) {
|
|
||||||
final View firstChild = mListView.getChildAt(savedChildIndex);
|
|
||||||
mListScrollOffset = firstChild != null ? firstChild.getTop() : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final long lastViewedId = mAdapter.getStatusId(listVisiblePosition);
|
|
||||||
mAdapter.setData(data);
|
|
||||||
mAdapter.setShowAccountColor(shouldShowAccountColor());
|
|
||||||
final int currFirstVisiblePosition = mListView.getFirstVisiblePosition();
|
|
||||||
final long currViewedId = mAdapter.getStatusId(currFirstVisiblePosition);
|
|
||||||
final long statusId;
|
|
||||||
if (lastViewedId <= 0) {
|
|
||||||
if (!rememberPosition) return;
|
|
||||||
statusId = mPositionManager.getPosition(getPositionKey());
|
|
||||||
} else if ((listVisiblePosition > 0 || rememberPosition) && currViewedId > 0 && lastViewedId != currViewedId) {
|
|
||||||
statusId = lastViewedId;
|
|
||||||
} else {
|
|
||||||
if (listVisiblePosition == 0 && mAdapter.getStatusId(0) != lastViewedId) {
|
|
||||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final int position = mAdapter.findPositionByStatusId(statusId);
|
|
||||||
if (position > -1 && position < mListView.getCount()) {
|
|
||||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
|
||||||
// mListView.setSelectionFromTop(position, mListScrollOffset);
|
|
||||||
mListView.setSelection(position);
|
|
||||||
mListScrollOffset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMenuButtonClick(final View button, final int position, final long id) {
|
|
||||||
if (mMultiSelectManager.isActive()) return;
|
|
||||||
final ParcelableStatus status = mAdapter.getStatus(position);
|
|
||||||
if (status == null) return;
|
|
||||||
openMenu(button, status, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean onMenuItemClick(final MenuItem item) {
|
|
||||||
final ParcelableStatus status = mSelectedStatus;
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (status == null || twitter == null) return false;
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case MENU_VIEW: {
|
|
||||||
openStatus(getActivity(), status, null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_SHARE: {
|
|
||||||
startStatusShareChooser(getActivity(), status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_COPY: {
|
|
||||||
if (ClipboardUtils.setText(getActivity(), status.text_plain)) {
|
|
||||||
showOkMessage(getActivity(), R.string.text_copied, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_RETWEET: {
|
|
||||||
if (isMyRetweet(status)) {
|
|
||||||
cancelRetweet(twitter, status);
|
|
||||||
} else {
|
|
||||||
final long id_to_retweet = status.retweet_id > 0 ? status.retweet_id : status.id;
|
|
||||||
twitter.retweetStatus(status.account_id, id_to_retweet);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_QUOTE: {
|
|
||||||
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
bundle.putParcelable(EXTRA_STATUS, status);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_REPLY: {
|
|
||||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
bundle.putParcelable(EXTRA_STATUS, status);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_FAVORITE: {
|
|
||||||
if (status.is_favorite) {
|
|
||||||
twitter.destroyFavoriteAsync(status.account_id, status.id);
|
|
||||||
} else {
|
|
||||||
twitter.createFavoriteAsync(status.account_id, status.id);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_DELETE: {
|
|
||||||
twitter.destroyStatusAsync(status.account_id, status.id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_ADD_TO_FILTER: {
|
|
||||||
AddStatusFilterDialogFragment.show(getFragmentManager(), status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_MULTI_SELECT: {
|
|
||||||
final boolean isSelected = !mMultiSelectManager.isSelected(status);
|
|
||||||
setItemSelected(status, mSelectedPosition, isSelected);
|
|
||||||
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 onRefreshFromEnd() {
|
|
||||||
if (mLoadMoreAutomatically) return;
|
|
||||||
loadMoreStatuses();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
|
|
||||||
configBaseCardAdapter(getActivity(), mAdapter);
|
|
||||||
final boolean display_image_preview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
|
||||||
final boolean display_sensitive_contents = mPreferences.getBoolean(KEY_DISPLAY_SENSITIVE_CONTENTS, false);
|
|
||||||
final boolean indicate_my_status = mPreferences.getBoolean(KEY_INDICATE_MY_STATUS, true);
|
|
||||||
mAdapter.setDisplayImagePreview(display_image_preview);
|
|
||||||
mAdapter.setDisplaySensitiveContents(display_sensitive_contents);
|
|
||||||
mAdapter.setIndicateMyStatusDisabled(isMyTimeline() || !indicate_my_status);
|
|
||||||
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
|
||||||
final int totalItemCount) {
|
|
||||||
super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
|
|
||||||
addReadPosition(firstVisibleItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
|
||||||
super.onScrollStateChanged(view, scrollState);
|
|
||||||
switch (scrollState) {
|
|
||||||
case SCROLL_STATE_IDLE:
|
|
||||||
for (int i = mListView.getFirstVisiblePosition(), j = mListView.getLastVisiblePosition(); i < j; i++) {
|
|
||||||
mReadPositions.add(i);
|
|
||||||
}
|
|
||||||
removeUnreadCounts();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
mMultiSelectManager.registerCallback(this);
|
|
||||||
final int choiceMode = mListView.getChoiceMode();
|
|
||||||
if (mMultiSelectManager.isActive()) {
|
|
||||||
if (choiceMode != ListView.CHOICE_MODE_MULTIPLE) {
|
|
||||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (choiceMode != ListView.CHOICE_MODE_NONE) {
|
|
||||||
Utils.clearListViewChoices(mListView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
savePosition();
|
|
||||||
mMultiSelectManager.unregisterCallback(this);
|
|
||||||
if (mPopupMenu != null) {
|
|
||||||
mPopupMenu.dismiss();
|
|
||||||
}
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean scrollToStart() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
final int tab_position = getTabPosition();
|
|
||||||
if (twitter != null && tab_position >= 0) {
|
|
||||||
twitter.clearUnreadCountAsync(tab_position);
|
|
||||||
}
|
|
||||||
return super.scrollToStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
|
||||||
updateRefreshState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final int getListScrollOffset() {
|
|
||||||
return mListScrollOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract long[] getNewestStatusIds();
|
|
||||||
|
|
||||||
protected abstract long[] getOldestStatusIds();
|
|
||||||
|
|
||||||
protected abstract String getPositionKey();
|
|
||||||
|
|
||||||
protected boolean isMyTimeline() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void loadMoreStatuses();
|
|
||||||
|
|
||||||
protected abstract IStatusesListAdapter<Data> newAdapterInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onReachedBottom() {
|
|
||||||
if (!mLoadMoreAutomatically) return;
|
|
||||||
loadMoreStatuses();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void savePosition() {
|
|
||||||
final int first_visible_position = mListView.getFirstVisiblePosition();
|
|
||||||
if (mListView.getChildCount() > 0) {
|
|
||||||
final View first_child = mListView.getChildAt(0);
|
|
||||||
mListScrollOffset = first_child != null ? first_child.getTop() : 0;
|
|
||||||
}
|
|
||||||
final long status_id = mAdapter.getStatusId(first_visible_position);
|
|
||||||
mPositionManager.setPosition(getPositionKey(), status_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void setData(final Data data) {
|
|
||||||
mData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setItemSelected(final ParcelableStatus status, final int position, final boolean selected) {
|
|
||||||
if (selected) {
|
|
||||||
mMultiSelectManager.selectItem(status);
|
|
||||||
} else {
|
|
||||||
mMultiSelectManager.unselectItem(status);
|
|
||||||
}
|
|
||||||
if (position >= 0) {
|
|
||||||
mListView.setItemChecked(position, selected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setListHeaderFooters(final StaggeredGridView list) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean shouldEnablePullToRefresh() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean shouldShowAccountColor();
|
|
||||||
|
|
||||||
protected abstract void updateRefreshState();
|
|
||||||
|
|
||||||
private void addReadPosition(final int firstVisibleItem) {
|
|
||||||
if (mFirstVisibleItem != firstVisibleItem) {
|
|
||||||
mReadPositions.add(firstVisibleItem);
|
|
||||||
}
|
|
||||||
mFirstVisibleItem = firstVisibleItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addUnreadCountsToRemove(final long account_id, final long id) {
|
|
||||||
if (mUnreadCountsToRemove.containsKey(account_id)) {
|
|
||||||
final Set<Long> counts = mUnreadCountsToRemove.get(account_id);
|
|
||||||
counts.add(id);
|
|
||||||
} else {
|
|
||||||
final Set<Long> counts = new HashSet<Long>();
|
|
||||||
counts.add(id);
|
|
||||||
mUnreadCountsToRemove.put(account_id, counts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openMenu(final View view, final ParcelableStatus status, final int position) {
|
|
||||||
mSelectedStatus = status;
|
|
||||||
mSelectedPosition = position;
|
|
||||||
if (view == null || status == null) return;
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
|
||||||
}
|
|
||||||
if (mPopupMenu != null && mPopupMenu.isShowing()) {
|
|
||||||
mPopupMenu.dismiss();
|
|
||||||
}
|
|
||||||
mPopupMenu = PopupMenu.getInstance(getActivity(), view);
|
|
||||||
mPopupMenu.inflate(R.menu.action_status);
|
|
||||||
final boolean longclickToOpenMenu = mPreferences.getBoolean(KEY_LONG_CLICK_TO_OPEN_MENU, false);
|
|
||||||
final Menu menu = mPopupMenu.getMenu();
|
|
||||||
setMenuForStatus(getActivity(), menu, status);
|
|
||||||
Utils.setMenuItemAvailability(menu, MENU_MULTI_SELECT, longclickToOpenMenu);
|
|
||||||
mPopupMenu.setOnMenuItemClickListener(this);
|
|
||||||
mPopupMenu.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeUnreadCounts() {
|
|
||||||
if (mRemoveUnreadCountsTask != null && mRemoveUnreadCountsTask.getStatus() == AsyncTask.Status.RUNNING)
|
|
||||||
return;
|
|
||||||
mRemoveUnreadCountsTask = new RemoveUnreadCountsTask<Data>(mReadPositions, this);
|
|
||||||
mRemoveUnreadCountsTask.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class RemoveUnreadCountsTask<T> extends AsyncTask<Void, Void, Void> {
|
|
||||||
private final List<Integer> read_positions;
|
|
||||||
private final IStatusesListAdapter<T> adapter;
|
|
||||||
private final BaseStatusesStaggeredGridFragment<T> fragment;
|
|
||||||
|
|
||||||
RemoveUnreadCountsTask(final List<Integer> read_positions, final BaseStatusesStaggeredGridFragment<T> fragment) {
|
|
||||||
this.read_positions = read_positions;
|
|
||||||
this.fragment = fragment;
|
|
||||||
this.adapter = fragment.getListAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(final Void... params) {
|
|
||||||
for (final int pos : read_positions) {
|
|
||||||
final long id = adapter.getStatusId(pos), account_id = adapter.getAccountId(pos);
|
|
||||||
fragment.addUnreadCountsToRemove(account_id, id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final Void result) {
|
|
||||||
final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
twitter.removeUnreadCountsAsync(fragment.getTabPosition(), fragment.getUnreadCountsToRemove());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -114,7 +114,8 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTabPosition() {
|
public int getTabPosition() {
|
||||||
return 0;
|
final Bundle args = getArguments();
|
||||||
|
return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,277 +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.support;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.AbsListView.OnScrollListener;
|
|
||||||
|
|
||||||
import com.etsy.android.grid.StaggeredGridView;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
|
||||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
|
||||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
|
||||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
|
||||||
import org.mariotaku.twidere.util.Utils;
|
|
||||||
|
|
||||||
public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment implements IBaseFragment, Constants,
|
|
||||||
OnScrollListener, RefreshScrollTopInterface {
|
|
||||||
|
|
||||||
private boolean mActivityFirstCreated;
|
|
||||||
private boolean mIsInstanceStateSaved;
|
|
||||||
private boolean mReachedBottom, mNotReachedBottomBefore = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void requestFitSystemWindows() {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
final Fragment parentFragment = getParentFragment();
|
|
||||||
final SystemWindowsInsetsCallback callback;
|
|
||||||
if (parentFragment instanceof SystemWindowsInsetsCallback) {
|
|
||||||
callback = (SystemWindowsInsetsCallback) parentFragment;
|
|
||||||
} else if (activity instanceof SystemWindowsInsetsCallback) {
|
|
||||||
callback = (SystemWindowsInsetsCallback) activity;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Rect insets = new Rect();
|
|
||||||
if (callback.getSystemWindowsInsets(insets)) {
|
|
||||||
fitSystemWindows(insets);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void fitSystemWindows(Rect insets) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public final TwidereApplication getApplication() {
|
|
||||||
return TwidereApplication.getInstance(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
public final ContentResolver getContentResolver() {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity != null) return activity.getContentResolver();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bundle getExtraConfiguration() {
|
|
||||||
final Bundle args = getArguments();
|
|
||||||
final Bundle extras = new Bundle();
|
|
||||||
if (args != null && args.containsKey(EXTRA_EXTRAS)) {
|
|
||||||
extras.putAll(args.getBundle(EXTRA_EXTRAS));
|
|
||||||
}
|
|
||||||
return extras;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final MultiSelectManager getMultiSelectManager() {
|
|
||||||
return getApplication() != null ? getApplication().getMultiSelectManager() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final SharedPreferences getSharedPreferences(final String name, final int mode) {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity != null) return activity.getSharedPreferences(name, mode);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Object getSystemService(final String name) {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity != null) return activity.getSystemService(name);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final int getTabPosition() {
|
|
||||||
final Bundle args = getArguments();
|
|
||||||
return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncTwitterWrapper getTwitterWrapper() {
|
|
||||||
return getApplication() != null ? getApplication().getTwitterWrapper() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void invalidateOptionsMenu() {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity == null) return;
|
|
||||||
activity.invalidateOptionsMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isActivityFirstCreated() {
|
|
||||||
return mActivityFirstCreated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInstanceStateSaved() {
|
|
||||||
return mIsInstanceStateSaved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReachedBottom() {
|
|
||||||
return mReachedBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
mIsInstanceStateSaved = savedInstanceState != null;
|
|
||||||
final StaggeredGridView lv = getListView();
|
|
||||||
lv.setOnScrollListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(final Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(final Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
mActivityFirstCreated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
|
||||||
return super.onCreateView(inflater, container, savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
mActivityFirstCreated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
super.onDetach();
|
|
||||||
final Fragment fragment = getParentFragment();
|
|
||||||
if (fragment instanceof SupportFragmentCallback) {
|
|
||||||
((SupportFragmentCallback) fragment).onDetachFragment(this);
|
|
||||||
}
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity instanceof SupportFragmentCallback) {
|
|
||||||
((SupportFragmentCallback) activity).onDetachFragment(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPostStart() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
|
||||||
final int totalItemCount) {
|
|
||||||
final boolean reached = firstVisibleItem + visibleItemCount >= totalItemCount
|
|
||||||
&& totalItemCount >= visibleItemCount;
|
|
||||||
|
|
||||||
if (mReachedBottom != reached) {
|
|
||||||
mReachedBottom = reached;
|
|
||||||
if (mReachedBottom && mNotReachedBottomBefore) {
|
|
||||||
mNotReachedBottomBefore = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mReachedBottom && getListAdapter().getCount() > visibleItemCount) {
|
|
||||||
onReachedBottom();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
onPostStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
mActivityFirstCreated = false;
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity == null) return;
|
|
||||||
activity.registerReceiver(receiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean scrollToStart() {
|
|
||||||
if (!isAdded() || getActivity() == null) return false;
|
|
||||||
Utils.scrollListToTop(getListView());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressBarIndeterminateVisibility(final boolean visible) {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity == null) return;
|
|
||||||
activity.setProgressBarIndeterminateVisibility(visible);
|
|
||||||
if (activity instanceof HomeActivity) {
|
|
||||||
((HomeActivity) activity).setHomeProgressBarIndeterminateVisibility(visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelection(final int position) {
|
|
||||||
Utils.scrollListToPosition(getListView(), position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
final Fragment fragment = getParentFragment();
|
|
||||||
if (fragment instanceof SupportFragmentCallback) {
|
|
||||||
((SupportFragmentCallback) fragment).onSetUserVisibleHint(this, isVisibleToUser);
|
|
||||||
}
|
|
||||||
if (activity instanceof SupportFragmentCallback) {
|
|
||||||
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean triggerRefresh() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unregisterReceiver(final BroadcastReceiver receiver) {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity == null) return;
|
|
||||||
activity.unregisterReceiver(receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onReachedBottom() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,18 +20,134 @@
|
||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.content.CursorLoader;
|
||||||
|
import android.support.v4.content.Loader;
|
||||||
|
|
||||||
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||||
|
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||||
|
import org.mariotaku.twidere.task.AsyncTask;
|
||||||
|
import org.mariotaku.twidere.util.Utils;
|
||||||
|
|
||||||
|
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
||||||
|
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
||||||
|
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
||||||
|
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
||||||
|
import static org.mariotaku.twidere.util.Utils.shouldEnableFiltersForRTs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/12/3.
|
* Created by mariotaku on 14/12/3.
|
||||||
*/
|
*/
|
||||||
public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor> {
|
public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor> {
|
||||||
|
|
||||||
|
|
||||||
|
public abstract Uri getContentUri();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
|
final Context context = getActivity();
|
||||||
|
final Uri uri = getContentUri();
|
||||||
|
final String table = getTableNameByUri(uri);
|
||||||
|
final String sortOrder = getSortOrder();
|
||||||
|
final long[] accountIds = getAccountIds();
|
||||||
|
final Expression accountWhere = Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
|
||||||
|
final Expression filterWhere = getFiltersWhere(table), where;
|
||||||
|
if (filterWhere != null) {
|
||||||
|
where = Expression.and(accountWhere, filterWhere);
|
||||||
|
} else {
|
||||||
|
where = accountWhere;
|
||||||
|
}
|
||||||
|
final String selection = processWhere(where).getSQL();
|
||||||
|
return new CursorLoader(context, uri, Statuses.COLUMNS, selection, null, sortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean triggerRefresh() {
|
||||||
|
new AsyncTask<Void, Void, long[][]>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long[][] doInBackground(final Void... params) {
|
||||||
|
final long[][] result = new long[3][];
|
||||||
|
result[0] = getAccountIds();
|
||||||
|
result[2] = getNewestStatusIds(result[0]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final long[][] result) {
|
||||||
|
getStatuses(result[0], result[1], result[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}.execute();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long[] getAccountIds() {
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
if (args != null && args.getLong(EXTRA_ACCOUNT_ID) > 0) {
|
||||||
|
return new long[]{args.getLong(EXTRA_ACCOUNT_ID)};
|
||||||
|
}
|
||||||
|
return Utils.getActivatedAccountIds(getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int getNotificationType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||||
return new CursorStatusesAdapter(context, compact);
|
return new CursorStatusesAdapter(context, compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoadMoreStatuses() {
|
||||||
|
new AsyncTask<Void, Void, long[][]>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long[][] doInBackground(final Void... params) {
|
||||||
|
final long[][] result = new long[3][];
|
||||||
|
result[0] = getAccountIds();
|
||||||
|
result[1] = getOldestStatusIds(result[0]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final long[][] result) {
|
||||||
|
getStatuses(result[0], result[1], result[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Expression getFiltersWhere(String table) {
|
||||||
|
if (!isFilterEnabled()) return null;
|
||||||
|
return buildStatusFilterWhereClause(table, null, shouldEnableFiltersForRTs(getActivity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean isFilterEnabled();
|
||||||
|
|
||||||
|
protected long[] getNewestStatusIds(long[] accountIds) {
|
||||||
|
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), accountIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected long[] getOldestStatusIds(long[] accountIds) {
|
||||||
|
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), accountIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Expression processWhere(final Expression where) {
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSortOrder() {
|
||||||
|
final SharedPreferences preferences = getSharedPreferences();
|
||||||
|
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
||||||
|
return sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,229 +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.support;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
|
||||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
|
|
||||||
|
|
||||||
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.shouldEnableFiltersForRTs;
|
|
||||||
|
|
||||||
public abstract class CursorStatusesListFragment extends BaseStatusesListFragment<Cursor> {
|
|
||||||
|
|
||||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
|
||||||
this, 0, this);
|
|
||||||
|
|
||||||
public HomeActivity getHomeActivity() {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity instanceof HomeActivity) return (HomeActivity) activity;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
getListAdapter().setFiltersEnabled(isFiltersEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
|
||||||
final Context context = getActivity();
|
|
||||||
final SharedPreferences preferences = getSharedPreferences();
|
|
||||||
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
|
||||||
final Uri uri = getContentUri();
|
|
||||||
final String table = getTableNameByUri(uri);
|
|
||||||
final String sortOrder = sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
|
||||||
final long accountId = getAccountId();
|
|
||||||
final long[] accountIds = accountId > 0 ? new long[]{accountId} : getActivatedAccountIds(context);
|
|
||||||
final boolean noAccountSelected = accountIds.length == 0;
|
|
||||||
setEmptyText(noAccountSelected ? getString(R.string.no_account_selected) : null);
|
|
||||||
if (!noAccountSelected) {
|
|
||||||
getListView().setEmptyView(null);
|
|
||||||
}
|
|
||||||
final Where accountWhere = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
|
|
||||||
final Where where;
|
|
||||||
if (isFiltersEnabled()) {
|
|
||||||
final Where filterWhere = new Where(buildStatusFilterWhereClause(table, null,
|
|
||||||
shouldEnableFiltersForRTs(context)));
|
|
||||||
where = Where.and(accountWhere, filterWhere);
|
|
||||||
} else {
|
|
||||||
where = accountWhere;
|
|
||||||
}
|
|
||||||
final String selection = processWhere(where).getSQL();
|
|
||||||
return new CursorLoader(context, uri, CursorStatusesListAdapter.CURSOR_COLS, selection, null, sortOrder);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRefreshFromStart() {
|
|
||||||
if (isRefreshing()) return;
|
|
||||||
savePosition();
|
|
||||||
new AsyncTask<Void, Void, long[][]>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[][] doInBackground(final Void... params) {
|
|
||||||
final long[][] result = new long[3][];
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
result[0] = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
|
||||||
result[2] = getNewestStatusIds();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final long[][] result) {
|
|
||||||
getStatuses(result[0], result[1], result[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRestart() {
|
|
||||||
super.onRestart();
|
|
||||||
getLoaderManager().restartLoader(0, getArguments(), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
|
||||||
super.onScrollStateChanged(view, scrollState);
|
|
||||||
switch (scrollState) {
|
|
||||||
case SCROLL_STATE_FLING:
|
|
||||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SCROLL_STATE_IDLE: {
|
|
||||||
savePosition();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final ContentResolver resolver = getContentResolver();
|
|
||||||
resolver.registerContentObserver(Filters.CONTENT_URI, true, mReloadContentObserver);
|
|
||||||
if (getAccountId() <= 0) {
|
|
||||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
savePosition();
|
|
||||||
final ContentResolver resolver = getContentResolver();
|
|
||||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getAccountId() {
|
|
||||||
final Bundle args = getArguments();
|
|
||||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Uri getContentUri();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[] getNewestStatusIds() {
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
final long[] account_ids = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
|
||||||
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract int getNotificationType();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[] getOldestStatusIds() {
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
final long[] account_ids = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
|
||||||
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean isFiltersEnabled();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void loadMoreStatuses() {
|
|
||||||
if (isRefreshing()) return;
|
|
||||||
savePosition();
|
|
||||||
new AsyncTask<Void, Void, long[][]>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[][] doInBackground(final Void... params) {
|
|
||||||
final long[][] result = new long[3][];
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
result[0] = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
|
||||||
result[1] = getOldestStatusIds();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final long[][] result) {
|
|
||||||
getStatuses(result[0], result[1], result[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CursorStatusesListAdapter newAdapterInstance(final boolean compact) {
|
|
||||||
return new CursorStatusesListAdapter(getActivity(), compact);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onListTouched() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
twitter.clearNotificationAsync(getNotificationType(), getAccountId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Where processWhere(final Where where) {
|
|
||||||
return where;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldShowAccountColor() {
|
|
||||||
return getAccountId() <= 0 && getActivatedAccountIds(getActivity()).length > 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,213 +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.support;
|
|
||||||
|
|
||||||
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
|
||||||
import static org.mariotaku.twidere.util.Utils.shouldEnableFiltersForRTs;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
|
||||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
|
|
||||||
|
|
||||||
public abstract class CursorStatusesStaggeredGridFragment extends BaseStatusesStaggeredGridFragment<Cursor> {
|
|
||||||
|
|
||||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
|
||||||
this, 0, this);
|
|
||||||
|
|
||||||
public HomeActivity getHomeActivity() {
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity instanceof HomeActivity) return (HomeActivity) activity;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
getListAdapter().setFiltersEnabled(isFiltersEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
|
||||||
final Uri uri = getContentUri();
|
|
||||||
final String table = getTableNameByUri(uri);
|
|
||||||
final String sort_by = Statuses.DEFAULT_SORT_ORDER;
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
|
||||||
final boolean no_account_selected = account_ids.length == 0;
|
|
||||||
setEmptyText(no_account_selected ? getString(R.string.no_account_selected) : null);
|
|
||||||
if (!no_account_selected) {
|
|
||||||
getListView().setEmptyView(null);
|
|
||||||
}
|
|
||||||
final Where accountWhere = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
|
||||||
final Where where;
|
|
||||||
if (isFiltersEnabled()) {
|
|
||||||
final Where filterWhere = new Where(buildStatusFilterWhereClause(table, null,
|
|
||||||
shouldEnableFiltersForRTs(getActivity())));
|
|
||||||
where = Where.and(accountWhere, filterWhere);
|
|
||||||
} else {
|
|
||||||
where = accountWhere;
|
|
||||||
}
|
|
||||||
return new CursorLoader(getActivity(), uri, CursorStatusesListAdapter.CURSOR_COLS, where.getSQL(), null, sort_by);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRefreshFromStart() {
|
|
||||||
if (isRefreshing()) return;
|
|
||||||
savePosition();
|
|
||||||
new AsyncTask<Void, Void, long[][]>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[][] doInBackground(final Void... params) {
|
|
||||||
final long[][] result = new long[3][];
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
result[0] = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
|
||||||
result[2] = getNewestStatusIds();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final long[][] result) {
|
|
||||||
getStatuses(result[0], result[1], result[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
|
||||||
super.onScrollStateChanged(view, scrollState);
|
|
||||||
switch (scrollState) {
|
|
||||||
case SCROLL_STATE_FLING:
|
|
||||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SCROLL_STATE_IDLE: {
|
|
||||||
savePosition();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final ContentResolver resolver = getContentResolver();
|
|
||||||
resolver.registerContentObserver(Filters.CONTENT_URI, true, mReloadContentObserver);
|
|
||||||
if (getAccountId() <= 0) {
|
|
||||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
savePosition();
|
|
||||||
final ContentResolver resolver = getContentResolver();
|
|
||||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long getAccountId() {
|
|
||||||
final Bundle args = getArguments();
|
|
||||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Uri getContentUri();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[] getNewestStatusIds() {
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
|
||||||
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract int getNotificationType();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[] getOldestStatusIds() {
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
|
||||||
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean isFiltersEnabled();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void loadMoreStatuses() {
|
|
||||||
if (isRefreshing()) return;
|
|
||||||
savePosition();
|
|
||||||
new AsyncTask<Void, Void, long[][]>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long[][] doInBackground(final Void... params) {
|
|
||||||
final long[][] result = new long[3][];
|
|
||||||
final long account_id = getAccountId();
|
|
||||||
result[0] = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
|
||||||
result[1] = getOldestStatusIds();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final long[][] result) {
|
|
||||||
getStatuses(result[0], result[1], result[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CursorStatusesListAdapter newAdapterInstance() {
|
|
||||||
return new CursorStatusesListAdapter(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onListTouched() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter != null) {
|
|
||||||
twitter.clearNotificationAsync(getNotificationType(), getAccountId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldShowAccountColor() {
|
|
||||||
return getAccountId() <= 0 && getActivatedAccountIds(getActivity()).length > 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -64,7 +64,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
|
||||||
import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter;
|
import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter;
|
||||||
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.ParcelableDirectMessage;
|
import org.mariotaku.twidere.model.ParcelableDirectMessage;
|
||||||
import org.mariotaku.twidere.model.ParcelableUser;
|
import org.mariotaku.twidere.model.ParcelableUser;
|
||||||
import org.mariotaku.twidere.provider.TweetStore;
|
import org.mariotaku.twidere.provider.TweetStore;
|
||||||
|
@ -134,7 +134,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private Account mSender;
|
private ParcelableAccount mSender;
|
||||||
private ParcelableUser mRecipient;
|
private ParcelableUser mRecipient;
|
||||||
private ImageLoaderWrapper mImageLoader;
|
private ImageLoaderWrapper mImageLoader;
|
||||||
private IColorLabelView mProfileImageContainer;
|
private IColorLabelView mProfileImageContainer;
|
||||||
|
@ -174,7 +174,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
|
||||||
}
|
}
|
||||||
mEditText.addTextChangedListener(this);
|
mEditText.addTextChangedListener(this);
|
||||||
|
|
||||||
final List<Account> accounts = Account.getAccountsList(getActivity(), false);
|
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(getActivity(), false);
|
||||||
mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts));
|
mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts));
|
||||||
mAccountSpinner.setOnItemSelectedListener(this);
|
mAccountSpinner.setOnItemSelectedListener(this);
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) {
|
public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) {
|
||||||
final Account account = (Account) mAccountSpinner.getSelectedItem();
|
final ParcelableAccount account = (ParcelableAccount) mAccountSpinner.getSelectedItem();
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
mAccountId = account.account_id;
|
mAccountId = account.account_id;
|
||||||
mSender = account;
|
mSender = account;
|
||||||
|
@ -487,7 +487,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
|
||||||
mAccountId = accountId;
|
mAccountId = accountId;
|
||||||
mRecipientId = recipientId;
|
mRecipientId = recipientId;
|
||||||
final Context context = getActivity();
|
final Context context = getActivity();
|
||||||
mSender = Account.getAccount(context, accountId);
|
mSender = ParcelableAccount.getAccount(context, accountId);
|
||||||
mRecipient = Utils.getUserForConversation(context, accountId, recipientId);
|
mRecipient = Utils.getUserForConversation(context, accountId, recipientId);
|
||||||
final LoaderManager lm = getLoaderManager();
|
final LoaderManager lm = getLoaderManager();
|
||||||
final Bundle args = new Bundle();
|
final Bundle args = new Bundle();
|
||||||
|
|
|
@ -37,8 +37,8 @@ import android.widget.AbsListView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.DirectMessageConversationEntriesAdapter;
|
import org.mariotaku.twidere.adapter.DirectMessageConversationEntriesAdapter;
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
|
@ -112,10 +112,7 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem
|
||||||
mAdapter = new DirectMessageConversationEntriesAdapter(getActivity());
|
mAdapter = new DirectMessageConversationEntriesAdapter(getActivity());
|
||||||
setListAdapter(mAdapter);
|
setListAdapter(mAdapter);
|
||||||
mListView = getListView();
|
mListView = getListView();
|
||||||
if (!mPreferences.getBoolean(KEY_COMPACT_CARDS, false)) {
|
mListView.setDivider(null);
|
||||||
mListView.setDivider(null);
|
|
||||||
}
|
|
||||||
mListView.setSelector(android.R.color.transparent);
|
|
||||||
getLoaderManager().initLoader(0, null, this);
|
getLoaderManager().initLoader(0, null, this);
|
||||||
setListShown(false);
|
setListShown(false);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +127,7 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem
|
||||||
if (!no_account_selected) {
|
if (!no_account_selected) {
|
||||||
getListView().setEmptyView(null);
|
getListView().setEmptyView(null);
|
||||||
}
|
}
|
||||||
final Where account_where = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
final Expression account_where = Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
||||||
return new CursorLoader(getActivity(), uri, null, account_where.getSQL(), null, null);
|
return new CursorLoader(getActivity(), uri, null, account_where.getSQL(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,33 +19,61 @@
|
||||||
|
|
||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||||
|
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 14/12/3.
|
* Created by mariotaku on 14/12/3.
|
||||||
*/
|
*/
|
||||||
public class HomeTimelineFragment extends CursorStatusesFragment {
|
public class HomeTimelineFragment extends CursorStatusesFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
public Uri getContentUri() {
|
||||||
return 0;
|
return Statuses.CONTENT_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
protected int getNotificationType() {
|
||||||
final Context context = getActivity();
|
return NOTIFICATION_ID_HOME_TIMELINE;
|
||||||
final Uri uri = Statuses.CONTENT_URI;
|
|
||||||
final SharedPreferences preferences = getSharedPreferences();
|
|
||||||
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
|
||||||
final String sortOrder = sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
|
||||||
return new CursorLoader(context, uri, CursorStatusesListAdapter.CURSOR_COLS, null, null, sortOrder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isFilterEnabled() {
|
||||||
|
final SharedPreferences pref = getSharedPreferences();
|
||||||
|
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||||
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||||
|
if (twitter == null) return -1;
|
||||||
|
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onReceivedBroadcast(Intent intent, String action) {
|
||||||
|
switch (action) {
|
||||||
|
case BROADCAST_TASK_STATE_CHANGED: {
|
||||||
|
updateRefreshState();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSetIntentFilter(IntentFilter filter) {
|
||||||
|
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRefreshState() {
|
||||||
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||||
|
if (twitter == null) return;
|
||||||
|
setRefreshing(twitter.isHomeTimelineRefreshing());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +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.support;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
|
|
||||||
public class HomeTimelineListFragment extends CursorStatusesListFragment {
|
|
||||||
|
|
||||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
|
||||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
|
||||||
final String action = intent.getAction();
|
|
||||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
|
||||||
setRefreshComplete();
|
|
||||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
|
||||||
updateRefreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter == null) return 0;
|
|
||||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
|
||||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
|
||||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
|
||||||
registerReceiver(mStatusReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
unregisterReceiver(mStatusReceiver);
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Uri getContentUri() {
|
|
||||||
return Statuses.CONTENT_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getNotificationType() {
|
|
||||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getPositionKey() {
|
|
||||||
return "home_timeline" + getTabPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isFiltersEnabled() {
|
|
||||||
final SharedPreferences pref = getSharedPreferences();
|
|
||||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateRefreshState() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
|
||||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,8 +5,8 @@ import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.Account.AccountWithCredentials;
|
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials;
|
||||||
import org.mariotaku.twidere.model.ParcelableUser;
|
import org.mariotaku.twidere.model.ParcelableUser;
|
||||||
|
|
||||||
public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragment {
|
public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragment {
|
||||||
|
@ -14,8 +14,8 @@ public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragmen
|
||||||
@Override
|
@Override
|
||||||
protected void onPrepareItemMenu(final Menu menu, final ParcelableUser user) {
|
protected void onPrepareItemMenu(final Menu menu, final ParcelableUser user) {
|
||||||
final Context context = getThemedContext();
|
final Context context = getThemedContext();
|
||||||
final AccountWithCredentials account = Account.getAccountWithCredentials(context, user.account_id);
|
final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(context, user.account_id);
|
||||||
if (AccountWithCredentials.isOfficialCredentials(context, account)) {
|
if (ParcelableAccountWithCredentials.isOfficialCredentials(context, account)) {
|
||||||
final MenuInflater inflater = new MenuInflater(context);
|
final MenuInflater inflater = new MenuInflater(context);
|
||||||
inflater.inflate(R.menu.action_incoming_friendship, menu);
|
inflater.inflate(R.menu.action_incoming_friendship, menu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
/*
|
/*
|
||||||
* Twidere - Twitter client for Android
|
* Twidere - Twitter client for Android
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
@ -25,89 +25,57 @@ import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Mentions;
|
import org.mariotaku.twidere.provider.TweetStore.Mentions;
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||||
|
|
||||||
public class MentionsTimelineFragment extends CursorStatusesListFragment {
|
/**
|
||||||
|
* Created by mariotaku on 14/12/3.
|
||||||
|
*/
|
||||||
|
public class MentionsTimelineFragment extends CursorStatusesFragment {
|
||||||
|
|
||||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
@Override
|
||||||
|
public Uri getContentUri() {
|
||||||
|
return Mentions.CONTENT_URI;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
protected int getNotificationType() {
|
||||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
return NOTIFICATION_ID_MENTIONS_TIMELINE;
|
||||||
final String action = intent.getAction();
|
}
|
||||||
if (BROADCAST_MENTIONS_REFRESHED.equals(action)) {
|
|
||||||
setRefreshComplete();
|
|
||||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
|
||||||
updateRefreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStatuses(final long[] account_ids, final long[] max_ids, final long[] since_ids) {
|
protected boolean isFilterEnabled() {
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
final SharedPreferences pref = getSharedPreferences();
|
||||||
if (twitter == null) return -1;
|
return pref != null && pref.getBoolean(KEY_FILTERS_IN_MENTIONS_TIMELINE, true);
|
||||||
return twitter.getMentionsAsync(account_ids, max_ids, since_ids);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||||
getListAdapter().setMentionsHightlightDisabled(true);
|
if (twitter == null) return -1;
|
||||||
}
|
return twitter.getMentionsTimelineAsync(accountIds, maxIds, sinceIds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
protected void onReceivedBroadcast(Intent intent, String action) {
|
||||||
super.onStart();
|
switch (action) {
|
||||||
final IntentFilter filter = new IntentFilter(BROADCAST_MENTIONS_REFRESHED);
|
case BROADCAST_TASK_STATE_CHANGED: {
|
||||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
updateRefreshState();
|
||||||
registerReceiver(mStatusReceiver, filter);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
protected void onSetIntentFilter(IntentFilter filter) {
|
||||||
unregisterReceiver(mStatusReceiver);
|
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||||
super.onStop();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private void updateRefreshState() {
|
||||||
protected Uri getContentUri() {
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||||
return Mentions.CONTENT_URI;
|
if (twitter == null) return;
|
||||||
}
|
setRefreshing(twitter.isMentionsTimelineRefreshing());
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected int getNotificationType() {
|
|
||||||
return NOTIFICATION_ID_MENTIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getPositionKey() {
|
|
||||||
return "mentions_timeline" + getTabPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isFiltersEnabled() {
|
|
||||||
final SharedPreferences pref = getSharedPreferences();
|
|
||||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_MENTIONS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Where processWhere(final Where where) {
|
|
||||||
final Bundle extras = getExtraConfiguration();
|
|
||||||
if (extras.getBoolean(EXTRA_MY_FOLLOWING_ONLY))
|
|
||||||
return Where.and(where, Where.equals(Mentions.IS_FOLLOWING, 1));
|
|
||||||
return where;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateRefreshState() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter == null || !getUserVisibleHint()) return;
|
|
||||||
setRefreshing(twitter.isMentionsRefreshing());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,15 @@
|
||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||||
|
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,8 +37,31 @@ import java.util.List;
|
||||||
public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<List<ParcelableStatus>> {
|
public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<List<ParcelableStatus>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
protected void onSetIntentFilter(IntentFilter filter) {
|
||||||
return new ParcelableStatusesAdapter(context, compact);
|
filter.addAction(BROADCAST_STATUS_DESTROYED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onReceivedBroadcast(Intent intent, String action) {
|
||||||
|
switch (action) {
|
||||||
|
case BROADCAST_STATUS_DESTROYED: {
|
||||||
|
deleteStatus(intent.getLongExtra(EXTRA_STATUS_ID, -1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void deleteStatus(final long statusId) {
|
||||||
|
final List<ParcelableStatus> data = getAdapterData();
|
||||||
|
if (statusId <= 0 || data == null) return;
|
||||||
|
final ArrayList<ParcelableStatus> dataToRemove = new ArrayList<>();
|
||||||
|
for (final ParcelableStatus status : data) {
|
||||||
|
if (status.id == statusId || status.retweet_id > 0 && status.retweet_id == statusId) {
|
||||||
|
dataToRemove.add(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.removeAll(dataToRemove);
|
||||||
|
setAdapterData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,4 +77,39 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long[] getAccountIds() {
|
||||||
|
return new long[]{getAccountId()};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||||
|
return new ParcelableStatusesAdapter(context, compact);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoadMoreStatuses() {
|
||||||
|
final IStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||||
|
final long[] maxIds = new long[]{adapter.getStatus(adapter.getStatusCount() - 1).id};
|
||||||
|
getStatuses(null, maxIds, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean triggerRefresh() {
|
||||||
|
final IStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||||
|
final long[] accountIds = getAccountIds();
|
||||||
|
if (adapter.getStatusCount() > 0) {
|
||||||
|
final long[] sinceIds = new long[]{adapter.getStatus(0).id};
|
||||||
|
getStatuses(accountIds, null, sinceIds);
|
||||||
|
} else {
|
||||||
|
getStatuses(accountIds, null, null);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected long getAccountId() {
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
||||||
if (statusId > 0) {
|
if (statusId > 0) {
|
||||||
deleteStatus(statusId);
|
deleteStatus(statusId);
|
||||||
}
|
}
|
||||||
} else if (BROADCAST_RETWEET_CHANGED.equals(action)) {
|
} else if (BROADCAST_STATUS_RETWEETED.equals(action)) {
|
||||||
final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1);
|
final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1);
|
||||||
final boolean retweeted = intent.getBooleanExtra(EXTRA_RETWEETED, false);
|
final boolean retweeted = intent.getBooleanExtra(EXTRA_RETWEETED, false);
|
||||||
if (status_id > 0 && !retweeted) {
|
if (status_id > 0 && !retweeted) {
|
||||||
|
@ -158,7 +158,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final IntentFilter filter = new IntentFilter(BROADCAST_STATUS_DESTROYED);
|
final IntentFilter filter = new IntentFilter(BROADCAST_STATUS_DESTROYED);
|
||||||
filter.addAction(BROADCAST_RETWEET_CHANGED);
|
filter.addAction(BROADCAST_STATUS_RETWEETED);
|
||||||
registerReceiver(mStateReceiver, filter);
|
registerReceiver(mStateReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,15 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll
|
||||||
|
|
||||||
private Fragment mCurrentVisibleFragment;
|
private Fragment mCurrentVisibleFragment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fitSystemWindows(Rect insets) {
|
||||||
|
super.fitSystemWindows(insets);
|
||||||
|
final View view = getView();
|
||||||
|
if (view != null) {
|
||||||
|
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fragment getCurrentVisibleFragment() {
|
public Fragment getCurrentVisibleFragment() {
|
||||||
return mCurrentVisibleFragment;
|
return mCurrentVisibleFragment;
|
||||||
|
|
|
@ -1,364 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2011 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.mariotaku.twidere.fragment.support;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.animation.AnimationUtils;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.etsy.android.grid.StaggeredGridView;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static library support version of the framework's
|
|
||||||
* {@link android.app.ListFragment}. Used to write apps that run on platforms
|
|
||||||
* prior to Android 3.0. When running on Android 3.0 or above, this
|
|
||||||
* implementation is still used; it does not try to switch to the framework's
|
|
||||||
* implementation. See the framework SDK documentation for a class overview.
|
|
||||||
*/
|
|
||||||
public class StaggeredGridFragment extends Fragment {
|
|
||||||
static final int INTERNAL_EMPTY_ID = 0x00ff0001;
|
|
||||||
static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
|
|
||||||
static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
|
|
||||||
|
|
||||||
final private Handler mHandler = new Handler();
|
|
||||||
|
|
||||||
final private Runnable mRequestFocus = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mList.focusableViewAvailable(mList);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(final AdapterView<?> parent, final View v, final int position, final long id) {
|
|
||||||
onListItemClick((StaggeredGridView) parent, v, position, id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ListAdapter mAdapter;
|
|
||||||
StaggeredGridView mList;
|
|
||||||
View mEmptyView;
|
|
||||||
TextView mStandardEmptyView;
|
|
||||||
View mProgressContainer;
|
|
||||||
View mListContainer;
|
|
||||||
CharSequence mEmptyText;
|
|
||||||
boolean mListShown;
|
|
||||||
|
|
||||||
public StaggeredGridFragment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ListAdapter associated with this activity's ListView.
|
|
||||||
*/
|
|
||||||
public ListAdapter getListAdapter() {
|
|
||||||
return mAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the activity's list view widget.
|
|
||||||
*/
|
|
||||||
public StaggeredGridView getListView() {
|
|
||||||
ensureList();
|
|
||||||
return mList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the cursor row ID of the currently selected list item.
|
|
||||||
*/
|
|
||||||
public long getSelectedItemId() {
|
|
||||||
ensureList();
|
|
||||||
return mList.getSelectedItemId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the position of the currently selected list item.
|
|
||||||
*/
|
|
||||||
public int getSelectedItemPosition() {
|
|
||||||
ensureList();
|
|
||||||
return mList.getSelectedItemPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide default implementation to return a simple list view. Subclasses
|
|
||||||
* can override to replace with their own layout. If doing so, the returned
|
|
||||||
* view hierarchy <em>must</em> have a ListView whose id is
|
|
||||||
* {@link android.R.id#list android.R.id.list} and can optionally have a
|
|
||||||
* sibling view id {@link android.R.id#empty android.R.id.empty} that is to
|
|
||||||
* be shown when the list is empty.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* If you are overriding this method with your own custom content, consider
|
|
||||||
* including the standard layout {@link android.R.layout#list_content} in
|
|
||||||
* your layout file, so that you continue to retain all of the standard
|
|
||||||
* behavior of ListFragment. In particular, this is currently the only way
|
|
||||||
* to have the built-in indeterminant progress state be shown.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
|
||||||
final Context context = getActivity();
|
|
||||||
|
|
||||||
final FrameLayout root = new FrameLayout(context);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
final LinearLayout pframe = new LinearLayout(context);
|
|
||||||
pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
|
|
||||||
pframe.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
pframe.setVisibility(View.GONE);
|
|
||||||
pframe.setGravity(Gravity.CENTER);
|
|
||||||
|
|
||||||
final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
|
|
||||||
pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
final FrameLayout lframe = new FrameLayout(context);
|
|
||||||
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
|
|
||||||
|
|
||||||
final TextView tv = new TextView(getActivity());
|
|
||||||
tv.setId(INTERNAL_EMPTY_ID);
|
|
||||||
tv.setGravity(Gravity.CENTER);
|
|
||||||
lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
final StaggeredGridView lv = (StaggeredGridView) inflater.inflate(R.layout.staggered_gridview, lframe, false);
|
|
||||||
lv.setId(android.R.id.list);
|
|
||||||
lv.setDrawSelectorOnTop(false);
|
|
||||||
lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detach from list view.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
mHandler.removeCallbacks(mRequestFocus);
|
|
||||||
mList = null;
|
|
||||||
mListShown = false;
|
|
||||||
mEmptyView = mProgressContainer = mListContainer = null;
|
|
||||||
mStandardEmptyView = null;
|
|
||||||
super.onDestroyView();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will be called when an item in the list is selected.
|
|
||||||
* Subclasses should override. Subclasses can call
|
|
||||||
* getListView().getItemAtPosition(position) if they need to access the data
|
|
||||||
* associated with the selected item.
|
|
||||||
*
|
|
||||||
* @param l The ListView where the click happened
|
|
||||||
* @param v The view that was clicked within the ListView
|
|
||||||
* @param position The position of the view in the list
|
|
||||||
* @param id The row id of the item that was clicked
|
|
||||||
*/
|
|
||||||
public void onListItemClick(final StaggeredGridView l, final View v, final int position, final long id) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attach to list view once the view hierarchy has been created.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
ensureList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default content for a ListFragment has a TextView that can be shown
|
|
||||||
* when the list is empty. If you would like to have it shown, call this
|
|
||||||
* method to supply the text it should use.
|
|
||||||
*/
|
|
||||||
public void setEmptyText(final CharSequence text) {
|
|
||||||
ensureList();
|
|
||||||
if (mStandardEmptyView == null) throw new IllegalStateException("Can't be used with a custom content view");
|
|
||||||
mStandardEmptyView.setText(text);
|
|
||||||
if (mEmptyText == null) {
|
|
||||||
mList.setEmptyView(mStandardEmptyView);
|
|
||||||
}
|
|
||||||
mEmptyText = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide the cursor for the list view.
|
|
||||||
*/
|
|
||||||
public void setListAdapter(final ListAdapter adapter) {
|
|
||||||
final boolean hadAdapter = mAdapter != null;
|
|
||||||
mAdapter = adapter;
|
|
||||||
if (mList != null) {
|
|
||||||
mList.setAdapter(adapter);
|
|
||||||
if (!mListShown && !hadAdapter) {
|
|
||||||
// The list was hidden, and previously didn't have an
|
|
||||||
// adapter. It is now time to show it.
|
|
||||||
setListShown(true, getView().getWindowToken() != null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Control whether the list is being displayed. You can make it not
|
|
||||||
* displayed if you are waiting for the initial data to show in it. During
|
|
||||||
* this time an indeterminant progress indicator will be shown instead.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Applications do not normally need to use this themselves. The default
|
|
||||||
* behavior of ListFragment is to start with the list not being shown, only
|
|
||||||
* showing it once an adapter is given with
|
|
||||||
* {@link #setListAdapter(ListAdapter)}. If the list at that point had not
|
|
||||||
* been shown, when it does get shown it will be do without the user ever
|
|
||||||
* seeing the hidden state.
|
|
||||||
*
|
|
||||||
* @param shown If true, the list view is shown; if false, the progress
|
|
||||||
* indicator. The initial value is true.
|
|
||||||
*/
|
|
||||||
public void setListShown(final boolean shown) {
|
|
||||||
setListShown(shown, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like {@link #setListShown(boolean)}, but no animation is used when
|
|
||||||
* transitioning from the previous state.
|
|
||||||
*/
|
|
||||||
public void setListShownNoAnimation(final boolean shown) {
|
|
||||||
setListShown(shown, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the currently selected list item to the specified position with the
|
|
||||||
* adapter's data
|
|
||||||
*
|
|
||||||
* @param position
|
|
||||||
*/
|
|
||||||
public void setSelection(final int position) {
|
|
||||||
ensureList();
|
|
||||||
mList.setSelection(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureList() {
|
|
||||||
if (mList != null) return;
|
|
||||||
final View root = getView();
|
|
||||||
if (root == null) throw new IllegalStateException("Content view not yet created");
|
|
||||||
if (root instanceof StaggeredGridView) {
|
|
||||||
mList = (StaggeredGridView) root;
|
|
||||||
} else {
|
|
||||||
mStandardEmptyView = (TextView) root.findViewById(INTERNAL_EMPTY_ID);
|
|
||||||
if (mStandardEmptyView == null) {
|
|
||||||
mEmptyView = root.findViewById(android.R.id.empty);
|
|
||||||
} else {
|
|
||||||
mStandardEmptyView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID);
|
|
||||||
mListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);
|
|
||||||
final View rawListView = root.findViewById(android.R.id.list);
|
|
||||||
if (!(rawListView instanceof StaggeredGridView)) {
|
|
||||||
if (rawListView == null)
|
|
||||||
throw new RuntimeException("Your content must have a StaggeredGridView whose id attribute is "
|
|
||||||
+ "'android.R.id.list'");
|
|
||||||
throw new RuntimeException("Content has view with id attribute 'android.R.id.list' "
|
|
||||||
+ "that is not a StaggeredGridView class");
|
|
||||||
}
|
|
||||||
mList = (StaggeredGridView) rawListView;
|
|
||||||
if (mEmptyView != null) {
|
|
||||||
mList.setEmptyView(mEmptyView);
|
|
||||||
} else if (mEmptyText != null) {
|
|
||||||
mStandardEmptyView.setText(mEmptyText);
|
|
||||||
mList.setEmptyView(mStandardEmptyView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mListShown = true;
|
|
||||||
mList.setOnItemClickListener(mOnClickListener);
|
|
||||||
if (mAdapter != null) {
|
|
||||||
final ListAdapter adapter = mAdapter;
|
|
||||||
mAdapter = null;
|
|
||||||
setListAdapter(adapter);
|
|
||||||
} else {
|
|
||||||
// We are starting without an adapter, so assume we won't
|
|
||||||
// have our data right away and start with the progress indicator.
|
|
||||||
if (mProgressContainer != null) {
|
|
||||||
setListShown(false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mHandler.post(mRequestFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Control whether the list is being displayed. You can make it not
|
|
||||||
* displayed if you are waiting for the initial data to show in it. During
|
|
||||||
* this time an indeterminant progress indicator will be shown instead.
|
|
||||||
*
|
|
||||||
* @param shown If true, the list view is shown; if false, the progress
|
|
||||||
* indicator. The initial value is true.
|
|
||||||
* @param animate If true, an animation will be used to transition to the
|
|
||||||
* new state.
|
|
||||||
*/
|
|
||||||
private void setListShown(final boolean shown, final boolean animate) {
|
|
||||||
ensureList();
|
|
||||||
if (mProgressContainer == null) throw new IllegalStateException("Can't be used with a custom content view");
|
|
||||||
if (mListShown == shown) return;
|
|
||||||
mListShown = shown;
|
|
||||||
if (shown) {
|
|
||||||
if (animate) {
|
|
||||||
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
|
|
||||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
|
|
||||||
} else {
|
|
||||||
mProgressContainer.clearAnimation();
|
|
||||||
mListContainer.clearAnimation();
|
|
||||||
}
|
|
||||||
mProgressContainer.setVisibility(View.GONE);
|
|
||||||
mListContainer.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
if (animate) {
|
|
||||||
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
|
|
||||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
|
|
||||||
} else {
|
|
||||||
mProgressContainer.clearAnimation();
|
|
||||||
mListContainer.clearAnimation();
|
|
||||||
}
|
|
||||||
mProgressContainer.setVisibility(View.VISIBLE);
|
|
||||||
mListContainer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.support;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
||||||
|
|
||||||
public class StaggeredHomeTimelineFragment extends CursorStatusesStaggeredGridFragment {
|
|
||||||
|
|
||||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
|
||||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
|
||||||
final String action = intent.getAction();
|
|
||||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
|
||||||
setRefreshComplete();
|
|
||||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
|
||||||
updateRefreshState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter == null) return 0;
|
|
||||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
|
||||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
|
||||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
|
||||||
registerReceiver(mStatusReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
unregisterReceiver(mStatusReceiver);
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Uri getContentUri() {
|
|
||||||
return Statuses.CONTENT_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getNotificationType() {
|
|
||||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getPositionKey() {
|
|
||||||
return "home_timeline" + getTabPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isFiltersEnabled() {
|
|
||||||
final SharedPreferences pref = getSharedPreferences();
|
|
||||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateRefreshState() {
|
|
||||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
||||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
|
||||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getRefreshIndicatorView() {
|
|
||||||
return getListView().getRefreshIndicatorView();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -74,8 +74,8 @@ import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||||
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.model.Account.AccountWithCredentials;
|
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials;
|
||||||
import org.mariotaku.twidere.model.ParcelableLocation;
|
import org.mariotaku.twidere.model.ParcelableLocation;
|
||||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
@ -203,7 +203,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BROADCAST_RETWEET_CHANGED: {
|
case BROADCAST_STATUS_RETWEETED: {
|
||||||
final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1);
|
final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1);
|
||||||
if (status_id > 0 && status_id == getStatusId()) {
|
if (status_id > 0 && status_id == getStatusId()) {
|
||||||
getStatus(true);
|
getStatus(true);
|
||||||
|
@ -561,9 +561,9 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||||
}
|
}
|
||||||
case R.id.favorites_container: {
|
case R.id.favorites_container: {
|
||||||
// TODO
|
// TODO
|
||||||
final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(),
|
final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(),
|
||||||
status.account_id);
|
status.account_id);
|
||||||
if (AccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
||||||
openStatusFavoriters(getActivity(), status.account_id, status.retweet_id > 0 ? status.retweet_id
|
openStatusFavoriters(getActivity(), status.account_id, status.retweet_id > 0 ? status.retweet_id
|
||||||
: status.id);
|
: status.id);
|
||||||
}
|
}
|
||||||
|
@ -689,7 +689,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||||
final IntentFilter filter = new IntentFilter();
|
final IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(BROADCAST_FRIENDSHIP_CHANGED);
|
filter.addAction(BROADCAST_FRIENDSHIP_CHANGED);
|
||||||
filter.addAction(BROADCAST_FAVORITE_CHANGED);
|
filter.addAction(BROADCAST_FAVORITE_CHANGED);
|
||||||
filter.addAction(BROADCAST_RETWEET_CHANGED);
|
filter.addAction(BROADCAST_STATUS_RETWEETED);
|
||||||
registerReceiver(mStatusReceiver, filter);
|
registerReceiver(mStatusReceiver, filter);
|
||||||
updateUserColor();
|
updateUserColor();
|
||||||
final int text_size = mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
final int text_size = mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
||||||
|
@ -814,9 +814,9 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MENU_TRANSLATE: {
|
case MENU_TRANSLATE: {
|
||||||
final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(),
|
final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(),
|
||||||
status.account_id);
|
status.account_id);
|
||||||
if (AccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
||||||
StatusTranslateDialogFragment.show(getFragmentManager(), status);
|
StatusTranslateDialogFragment.show(getFragmentManager(), status);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
|
||||||
@Override
|
@Override
|
||||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
final List<ParcelableStatus> data = getAdapterData();
|
|
||||||
final Context context = getActivity();
|
final Context context = getActivity();
|
||||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||||
|
@ -44,8 +43,8 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
|
||||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||||
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||||
return new UserFavoritesLoader(context, accountId, userId, screenName, maxId, sinceId, data,
|
return new UserFavoritesLoader(context, accountId, userId, screenName, maxId, sinceId,
|
||||||
null, tabPosition);
|
getAdapterData(), null, tabPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
|
|
||||||
import org.mariotaku.menucomponent.internal.menu.MenuUtils;
|
import org.mariotaku.menucomponent.internal.menu.MenuUtils;
|
||||||
import org.mariotaku.querybuilder.Where;
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
||||||
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||||
|
@ -332,7 +332,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||||
mFollowButton.setText(R.string.follow);
|
mFollowButton.setText(R.string.follow);
|
||||||
}
|
}
|
||||||
final ContentResolver resolver = getContentResolver();
|
final ContentResolver resolver = getContentResolver();
|
||||||
final String where = Where.equals(CachedUsers.USER_ID, user.id).getSQL();
|
final String where = Expression.equals(CachedUsers.USER_ID, user.id).getSQL();
|
||||||
resolver.delete(CachedUsers.CONTENT_URI, where, null);
|
resolver.delete(CachedUsers.CONTENT_URI, where, null);
|
||||||
// I bet you don't want to see blocked user in your auto
|
// I bet you don't want to see blocked user in your auto
|
||||||
// complete list.
|
// complete list.
|
||||||
|
@ -926,7 +926,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||||
final boolean filtering = Utils.isFilteringUser(getActivity(), user.id);
|
final boolean filtering = Utils.isFilteringUser(getActivity(), user.id);
|
||||||
final ContentResolver cr = getContentResolver();
|
final ContentResolver cr = getContentResolver();
|
||||||
if (filtering) {
|
if (filtering) {
|
||||||
final Where where = Where.equals(Filters.Users.USER_ID, user.id);
|
final Expression where = Expression.equals(Filters.Users.USER_ID, user.id);
|
||||||
cr.delete(Filters.Users.CONTENT_URI, where.getSQL(), null);
|
cr.delete(Filters.Users.CONTENT_URI, where.getSQL(), null);
|
||||||
showInfoMessage(getActivity(), R.string.message_user_unmuted, false);
|
showInfoMessage(getActivity(), R.string.message_user_unmuted, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1115,7 +1115,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||||
final Drawable shadow = activity.getResources().getDrawable(R.drawable.shadow_user_banner_action_bar);
|
final Drawable shadow = activity.getResources().getDrawable(R.drawable.shadow_user_banner_action_bar);
|
||||||
final Drawable background = ThemeUtils.getActionBarBackground(activity, themeResId);
|
final Drawable background = ThemeUtils.getActionBarBackground(activity, themeResId);
|
||||||
mActionBarBackground = new ActionBarDrawable(getResources(), shadow, background, ThemeUtils.isDarkTheme(themeResId));
|
mActionBarBackground = new ActionBarDrawable(getResources(), shadow, background, ThemeUtils.isDarkTheme(themeResId));
|
||||||
mActionBarBackground.setAlpha(ThemeUtils.getThemeAlpha(activity));
|
mActionBarBackground.setAlpha(linkHandler.getCurrentThemeBackgroundAlpha());
|
||||||
|
mProfileBannerView.setAlpha(linkHandler.getCurrentThemeBackgroundAlpha() / 255f);
|
||||||
actionBar.setBackgroundDrawable(mActionBarBackground);
|
actionBar.setBackgroundDrawable(mActionBarBackground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1161,8 +1162,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||||
final View profileBannerContainer = mProfileBannerContainer;
|
final View profileBannerContainer = mProfileBannerContainer;
|
||||||
final int spaceHeight = space.getHeight();
|
final int spaceHeight = space.getHeight();
|
||||||
final float factor = MathUtils.clamp(offset / (float) spaceHeight, 0, 1);
|
final float factor = MathUtils.clamp(offset / (float) spaceHeight, 0, 1);
|
||||||
profileBannerView.setAlpha(1.0f - factor / 8f);
|
profileBannerContainer.setTranslationY(Math.max(-offset, -spaceHeight));
|
||||||
profileBannerContainer.setTranslationY(-offset);
|
|
||||||
profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / 2);
|
profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / 2);
|
||||||
|
|
||||||
if (mActionBarBackground != null && mTintedStatusContent != null) {
|
if (mActionBarBackground != null && mTintedStatusContent != null) {
|
||||||
|
|
|
@ -32,12 +32,14 @@ import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.support.v4.content.AsyncTaskLoader;
|
import android.support.v4.content.AsyncTaskLoader;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.widget.CardView;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -59,6 +61,7 @@ import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
||||||
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
||||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
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.ParcelableUser;
|
||||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||||
import org.mariotaku.twidere.model.SingleResponse;
|
import org.mariotaku.twidere.model.SingleResponse;
|
||||||
|
@ -86,7 +89,7 @@ import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability;
|
||||||
|
|
||||||
public class UserListFragment extends BaseSupportFragment implements OnClickListener,
|
public class UserListFragment extends BaseSupportFragment implements OnClickListener,
|
||||||
LoaderCallbacks<SingleResponse<ParcelableUserList>>, DrawerCallback,
|
LoaderCallbacks<SingleResponse<ParcelableUserList>>, DrawerCallback,
|
||||||
SystemWindowsInsetsCallback {
|
SystemWindowsInsetsCallback, SupportFragmentCallback {
|
||||||
|
|
||||||
private ImageLoaderWrapper mProfileImageLoader;
|
private ImageLoaderWrapper mProfileImageLoader;
|
||||||
private AsyncTwitterWrapper mTwitterWrapper;
|
private AsyncTwitterWrapper mTwitterWrapper;
|
||||||
|
@ -100,6 +103,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
private HeaderDrawerLayout mHeaderDrawerLayout;
|
private HeaderDrawerLayout mHeaderDrawerLayout;
|
||||||
private ViewPager mViewPager;
|
private ViewPager mViewPager;
|
||||||
private PagerSlidingTabStrip mPagerIndicator;
|
private PagerSlidingTabStrip mPagerIndicator;
|
||||||
|
private CardView mCardView;
|
||||||
|
|
||||||
private SupportTabsAdapter mPagerAdapter;
|
private SupportTabsAdapter mPagerAdapter;
|
||||||
|
|
||||||
|
@ -125,6 +129,59 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private boolean mUserListLoaderInitialized;
|
private boolean mUserListLoaderInitialized;
|
||||||
|
private Fragment mCurrentVisibleFragment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canScroll(float dy) {
|
||||||
|
final Fragment fragment = mCurrentVisibleFragment;
|
||||||
|
return fragment instanceof DrawerCallback && ((DrawerCallback) fragment).canScroll(dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTouch() {
|
||||||
|
final Fragment fragment = mCurrentVisibleFragment;
|
||||||
|
if (fragment instanceof DrawerCallback) {
|
||||||
|
((DrawerCallback) fragment).cancelTouch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fling(float velocity) {
|
||||||
|
final Fragment fragment = mCurrentVisibleFragment;
|
||||||
|
if (fragment instanceof DrawerCallback) {
|
||||||
|
((DrawerCallback) fragment).fling(velocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isScrollContent(float x, float y) {
|
||||||
|
final ViewPager v = mViewPager;
|
||||||
|
final int[] location = new int[2];
|
||||||
|
v.getLocationOnScreen(location);
|
||||||
|
return x >= location[0] && x <= location[0] + v.getWidth()
|
||||||
|
&& y >= location[1] && y <= location[1] + v.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scrollBy(float dy) {
|
||||||
|
final Fragment fragment = mCurrentVisibleFragment;
|
||||||
|
if (fragment instanceof DrawerCallback) {
|
||||||
|
((DrawerCallback) fragment).scrollBy(dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldLayoutHeaderBottom() {
|
||||||
|
final HeaderDrawerLayout drawer = mHeaderDrawerLayout;
|
||||||
|
final CardView card = mCardView;
|
||||||
|
if (drawer == null || card == null) return false;
|
||||||
|
return card.getTop() + drawer.getHeaderTop() - drawer.getPaddingTop() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void topChanged(int offset) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void displayUserList(final ParcelableUserList userList) {
|
public void displayUserList(final ParcelableUserList userList) {
|
||||||
if (userList == null || getActivity() == null) return;
|
if (userList == null || getActivity() == null) return;
|
||||||
|
@ -149,6 +206,31 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getCurrentVisibleFragment() {
|
||||||
|
return mCurrentVisibleFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachFragment(Fragment fragment) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetUserVisibleHint(Fragment fragment, boolean isVisibleToUser) {
|
||||||
|
mCurrentVisibleFragment = isVisibleToUser ? fragment : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean triggerRefresh(int position) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getSystemWindowsInsets(Rect insets) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void getUserListInfo(final boolean omit_intent_extra) {
|
public void getUserListInfo(final boolean omit_intent_extra) {
|
||||||
final LoaderManager lm = getLoaderManager();
|
final LoaderManager lm = getLoaderManager();
|
||||||
lm.destroyLoader(0);
|
lm.destroyLoader(0);
|
||||||
|
@ -320,29 +402,6 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupUserPages() {
|
|
||||||
final Context context = getActivity();
|
|
||||||
final Bundle args = getArguments(), tabArgs = new Bundle();
|
|
||||||
if (args.containsKey(EXTRA_USER)) {
|
|
||||||
final ParcelableUserList userList = args.getParcelable(EXTRA_USER_LIST);
|
|
||||||
tabArgs.putLong(EXTRA_ACCOUNT_ID, userList.account_id);
|
|
||||||
tabArgs.putLong(EXTRA_USER_ID, userList.user_id);
|
|
||||||
tabArgs.putString(EXTRA_SCREEN_NAME, userList.user_screen_name);
|
|
||||||
tabArgs.putInt(EXTRA_LIST_ID, (int) userList.id);
|
|
||||||
tabArgs.putString(EXTRA_LIST_NAME, userList.name);
|
|
||||||
} else {
|
|
||||||
tabArgs.putLong(EXTRA_ACCOUNT_ID, args.getLong(EXTRA_ACCOUNT_ID, -1));
|
|
||||||
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
|
|
||||||
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
|
|
||||||
tabArgs.putInt(EXTRA_LIST_ID, args.getInt(EXTRA_LIST_ID, -1));
|
|
||||||
tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME));
|
|
||||||
}
|
|
||||||
mPagerAdapter.addTab(UserListTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
|
|
||||||
mPagerAdapter.addTab(UserListMembersFragment.class, tabArgs, getString(R.string.list_members), null, 1);
|
|
||||||
mPagerAdapter.addTab(UserListSubscribersFragment.class, tabArgs, getString(R.string.list_subscribers), null, 2);
|
|
||||||
mPagerIndicator.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final View view) {
|
public void onClick(final View view) {
|
||||||
switch (view.getId()) {
|
switch (view.getId()) {
|
||||||
|
@ -415,6 +474,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
|
|
||||||
final View headerView = mHeaderDrawerLayout.getHeader();
|
final View headerView = mHeaderDrawerLayout.getHeader();
|
||||||
final View contentView = mHeaderDrawerLayout.getContent();
|
final View contentView = mHeaderDrawerLayout.getContent();
|
||||||
|
mCardView = (CardView) headerView.findViewById(R.id.card);
|
||||||
mProfileContainer = (ColorLabelRelativeLayout) headerView.findViewById(R.id.profile);
|
mProfileContainer = (ColorLabelRelativeLayout) headerView.findViewById(R.id.profile);
|
||||||
mListNameView = (TextView) headerView.findViewById(R.id.list_name);
|
mListNameView = (TextView) headerView.findViewById(R.id.list_name);
|
||||||
mCreatedByView = (TextView) headerView.findViewById(R.id.created_by);
|
mCreatedByView = (TextView) headerView.findViewById(R.id.created_by);
|
||||||
|
@ -441,44 +501,27 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||||
content.setClipToPadding(false);
|
content.setClipToPadding(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupUserPages() {
|
||||||
public void fling(float velocity) {
|
final Context context = getActivity();
|
||||||
|
final Bundle args = getArguments(), tabArgs = new Bundle();
|
||||||
}
|
if (args.containsKey(EXTRA_USER)) {
|
||||||
|
final ParcelableUserList userList = args.getParcelable(EXTRA_USER_LIST);
|
||||||
@Override
|
tabArgs.putLong(EXTRA_ACCOUNT_ID, userList.account_id);
|
||||||
public void scrollBy(float dy) {
|
tabArgs.putLong(EXTRA_USER_ID, userList.user_id);
|
||||||
|
tabArgs.putString(EXTRA_SCREEN_NAME, userList.user_screen_name);
|
||||||
}
|
tabArgs.putInt(EXTRA_LIST_ID, (int) userList.id);
|
||||||
|
tabArgs.putString(EXTRA_LIST_NAME, userList.name);
|
||||||
@Override
|
} else {
|
||||||
public boolean shouldLayoutHeaderBottom() {
|
tabArgs.putLong(EXTRA_ACCOUNT_ID, args.getLong(EXTRA_ACCOUNT_ID, -1));
|
||||||
return false;
|
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
|
||||||
}
|
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
|
||||||
|
tabArgs.putInt(EXTRA_LIST_ID, args.getInt(EXTRA_LIST_ID, -1));
|
||||||
@Override
|
tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME));
|
||||||
public boolean canScroll(float dy) {
|
}
|
||||||
return false;
|
mPagerAdapter.addTab(UserListTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
|
||||||
}
|
mPagerAdapter.addTab(UserListMembersFragment.class, tabArgs, getString(R.string.list_members), null, 1);
|
||||||
|
mPagerAdapter.addTab(UserListSubscribersFragment.class, tabArgs, getString(R.string.list_subscribers), null, 2);
|
||||||
@Override
|
mPagerIndicator.notifyDataSetChanged();
|
||||||
public boolean isScrollContent(float x, float y) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelTouch() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void topChanged(int offset) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getSystemWindowsInsets(Rect insets) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EditUserListDialogFragment extends BaseSupportDialogFragment implements
|
public static class EditUserListDialogFragment extends BaseSupportDialogFragment implements
|
||||||
|
|
|
@ -1,75 +1,51 @@
|
||||||
/*
|
/*
|
||||||
* Twidere - Twitter client for Android
|
* Twidere - Twitter client for Android
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
|
|
||||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
|
||||||
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
|
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UserListTimelineFragment extends ParcelableStatusesListFragment {
|
/**
|
||||||
|
* Created by mariotaku on 14/12/2.
|
||||||
|
*/
|
||||||
|
public class UserListTimelineFragment extends ParcelableStatusesFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||||
if (args == null) return null;
|
setRefreshing(true);
|
||||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
if (args == null) return null;
|
||||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
final int listId = args.getInt(EXTRA_LIST_ID, -1);
|
||||||
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||||
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
||||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||||
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
final String listName = args.getString(EXTRA_LIST_NAME);
|
||||||
return new UserListTimelineLoader(getActivity(), account_id, list_id, user_id, screen_name, list_name, max_id,
|
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||||
since_id, getData(), getSavedStatusesFileArgs(), tab_position);
|
return new UserListTimelineLoader(getActivity(), accountId, listId, userId, screenName,
|
||||||
}
|
listName, maxId, sinceId, getAdapterData(), null, tabPosition);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
|
||||||
adapter.setFiltersEnabled(true);
|
|
||||||
adapter.setIgnoredFilterFields(false, false, false, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String[] getSavedStatusesFileArgs() {
|
|
||||||
final Bundle args = getArguments();
|
|
||||||
if (args == null) return null;
|
|
||||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
|
||||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
|
||||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
|
||||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
|
||||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
|
||||||
return new String[] { AUTHORITY_USER_LIST_TIMELINE, "account" + account_id, "list_id" + list_id,
|
|
||||||
"list_name" + list_name, "user" + user_id, "screen_name" + screen_name };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldShowAccountColor() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.support;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.content.Loader;
|
||||||
|
|
||||||
|
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||||
|
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
|
||||||
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UserListTimelineListFragment extends ParcelableStatusesListFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||||
|
if (args == null) return null;
|
||||||
|
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||||
|
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||||
|
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
||||||
|
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
||||||
|
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||||
|
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||||
|
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||||
|
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||||
|
return new UserListTimelineLoader(getActivity(), account_id, list_id, user_id, screen_name, list_name, max_id,
|
||||||
|
since_id, getData(), getSavedStatusesFileArgs(), tab_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||||
|
adapter.setFiltersEnabled(true);
|
||||||
|
adapter.setIgnoredFilterFields(false, false, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getSavedStatusesFileArgs() {
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
if (args == null) return null;
|
||||||
|
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||||
|
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||||
|
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||||
|
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||||
|
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||||
|
return new String[] { AUTHORITY_USER_LIST_TIMELINE, "account" + account_id, "list_id" + list_id,
|
||||||
|
"list_name" + list_name, "user" + user_id, "screen_name" + screen_name };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldShowAccountColor() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,19 +9,19 @@ import android.view.SubMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.mariotaku.twidere.TwidereConstants;
|
import org.mariotaku.twidere.TwidereConstants;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
|
|
||||||
public class AccountActionProvider extends ActionProvider implements TwidereConstants {
|
public class AccountActionProvider extends ActionProvider implements TwidereConstants {
|
||||||
|
|
||||||
public static final int MENU_GROUP = 201;
|
public static final int MENU_GROUP = 201;
|
||||||
|
|
||||||
private final Account[] mAccounts;
|
private final ParcelableAccount[] mAccounts;
|
||||||
|
|
||||||
private long mAccountId;
|
private long mAccountId;
|
||||||
|
|
||||||
public AccountActionProvider(final Context context) {
|
public AccountActionProvider(final Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
mAccounts = Account.getAccounts(context, false, false);
|
mAccounts = ParcelableAccount.getAccounts(context, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,7 +37,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareSubMenu(final SubMenu subMenu) {
|
public void onPrepareSubMenu(final SubMenu subMenu) {
|
||||||
subMenu.removeGroup(MENU_GROUP);
|
subMenu.removeGroup(MENU_GROUP);
|
||||||
for (final Account account : mAccounts) {
|
for (final ParcelableAccount account : mAccounts) {
|
||||||
final MenuItem item = subMenu.add(MENU_GROUP, Menu.NONE, 0, account.name);
|
final MenuItem item = subMenu.add(MENU_GROUP, Menu.NONE, 0, account.name);
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.putExtra(EXTRA_ACCOUNT, account);
|
intent.putExtra(EXTRA_ACCOUNT, account);
|
||||||
|
@ -47,7 +47,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons
|
||||||
for (int i = 0, j = subMenu.size(); i < j; i++) {
|
for (int i = 0, j = subMenu.size(); i < j; i++) {
|
||||||
final MenuItem item = subMenu.getItem(i);
|
final MenuItem item = subMenu.getItem(i);
|
||||||
final Intent intent = item.getIntent();
|
final Intent intent = item.getIntent();
|
||||||
final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
|
final ParcelableAccount account = intent.getParcelableExtra(EXTRA_ACCOUNT);
|
||||||
if (account.account_id == mAccountId) {
|
if (account.account_id == mAccountId) {
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class AccountPreferences implements Constants {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDefaultNotificationLightColor() {
|
public int getDefaultNotificationLightColor() {
|
||||||
final Account a = Account.getAccount(mContext, mAccountId);
|
final ParcelableAccount a = ParcelableAccount.getAccount(mContext, mAccountId);
|
||||||
return a != null ? a.color : mContext.getResources().getColor(R.color.material_light_blue);
|
return a != null ? a.color : mContext.getResources().getColor(R.color.material_light_blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,176 +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.model;
|
|
||||||
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
|
||||||
import org.mariotaku.twidere.R;
|
|
||||||
import org.mariotaku.twidere.fragment.support.ActivitiesAboutMeFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.ActivitiesByFriendsFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.HomeTimelineFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.HomeTimelineListFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.SearchStatusesFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
|
||||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
public enum CustomTabConfiguration2 implements Constants {
|
|
||||||
|
|
||||||
HOME_TIMELINE(HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
|
||||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false),
|
|
||||||
|
|
||||||
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
|
||||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false),
|
|
||||||
|
|
||||||
DIRECT_MESSAGES(DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
|
||||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false),
|
|
||||||
|
|
||||||
TRENDS_SUGGESTIONS(TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
|
||||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true),
|
|
||||||
|
|
||||||
FAVORITES(UserFavoritesFragment.class, R.string.favorites, R.drawable.ic_action_star,
|
|
||||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 4),
|
|
||||||
|
|
||||||
USER_TIMELINE(UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
|
||||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5),
|
|
||||||
|
|
||||||
SEARCH_STATUSES(SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
|
||||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
|
||||||
EXTRA_QUERY, 6),
|
|
||||||
|
|
||||||
LIST_TIMELINE(UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
|
||||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7),
|
|
||||||
|
|
||||||
ACTIVITIES_ABOUT_ME(ActivitiesAboutMeFragment.class, R.string.activities_about_me,
|
|
||||||
R.drawable.ic_action_user, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
|
||||||
CustomTabConfiguration.FIELD_TYPE_NONE, 8),
|
|
||||||
|
|
||||||
ACTIVITIES_BY_FRIENDS(ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
|
||||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
|
||||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9);
|
|
||||||
|
|
||||||
public static final int FIELD_TYPE_NONE = 0;
|
|
||||||
public static final int FIELD_TYPE_USER = 1;
|
|
||||||
public static final int FIELD_TYPE_USER_LIST = 2;
|
|
||||||
public static final int FIELD_TYPE_TEXT = 3;
|
|
||||||
|
|
||||||
public static final int ACCOUNT_NONE = 0;
|
|
||||||
public static final int ACCOUNT_REQUIRED = 1;
|
|
||||||
public static final int ACCOUNT_OPTIONAL = 2;
|
|
||||||
|
|
||||||
private final int title, icon, secondaryFieldType, secondaryFieldTitle, sortPosition, accountRequirement;
|
|
||||||
private final Class<? extends Fragment> cls;
|
|
||||||
private final String secondaryFieldTextKey;
|
|
||||||
private final boolean singleTab;
|
|
||||||
|
|
||||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
|
||||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition) {
|
|
||||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
|
||||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition, final boolean singleTab) {
|
|
||||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, singleTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
|
||||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
|
||||||
final String secondaryFieldTextKey, final int sortPosition) {
|
|
||||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, secondaryFieldTextKey, sortPosition, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
|
||||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
|
||||||
final String secondaryFieldTextKey, final int sortPosition, final boolean singleTab) {
|
|
||||||
this.cls = cls;
|
|
||||||
this.title = title;
|
|
||||||
this.icon = icon;
|
|
||||||
this.sortPosition = sortPosition;
|
|
||||||
this.accountRequirement = accountRequirement;
|
|
||||||
this.secondaryFieldType = secondaryFieldType;
|
|
||||||
this.secondaryFieldTitle = secondaryFieldTitle;
|
|
||||||
this.secondaryFieldTextKey = secondaryFieldTextKey;
|
|
||||||
this.singleTab = singleTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAccountRequirement() {
|
|
||||||
return accountRequirement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDefaultIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDefaultTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<? extends Fragment> getFragmentClass() {
|
|
||||||
return cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecondaryFieldTextKey() {
|
|
||||||
return secondaryFieldTextKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSecondaryFieldTitle() {
|
|
||||||
return secondaryFieldTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSecondaryFieldType() {
|
|
||||||
return secondaryFieldType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSortPosition() {
|
|
||||||
return sortPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSingleTab() {
|
|
||||||
return singleTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "CustomTabConfiguration{title=" + title + ", icon=" + icon + ", secondaryFieldType="
|
|
||||||
+ secondaryFieldType + ", secondaryFieldTitle=" + secondaryFieldTitle + ", sortPosition="
|
|
||||||
+ sortPosition + ", accountRequirement=" + accountRequirement + ", cls=" + cls
|
|
||||||
+ ", secondaryFieldTextKey=" + secondaryFieldTextKey + ", singleTab=" + singleTab + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomTabConfigurationComparator implements Comparator<Entry<String, CustomTabConfiguration2>> {
|
|
||||||
|
|
||||||
public static final CustomTabConfigurationComparator SINGLETON = new CustomTabConfigurationComparator();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(final Entry<String, CustomTabConfiguration2> lhs,
|
|
||||||
final Entry<String, CustomTabConfiguration2> rhs) {
|
|
||||||
return lhs.getValue().getSortPosition() - rhs.getValue().getSortPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -80,7 +80,7 @@ public class DraftItem implements Parcelable {
|
||||||
|
|
||||||
public DraftItem(final ParcelableStatusUpdate status) {
|
public DraftItem(final ParcelableStatusUpdate status) {
|
||||||
_id = 0;
|
_id = 0;
|
||||||
account_ids = Account.getAccountIds(status.accounts);
|
account_ids = ParcelableAccount.getAccountIds(status.accounts);
|
||||||
in_reply_to_status_id = status.in_reply_to_status_id;
|
in_reply_to_status_id = status.in_reply_to_status_id;
|
||||||
text = status.text;
|
text = status.text;
|
||||||
media = status.media;
|
media = status.media;
|
||||||
|
|
|
@ -27,8 +27,8 @@ import android.os.Parcelable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.mariotaku.querybuilder.Columns.Column;
|
import org.mariotaku.querybuilder.Columns.Column;
|
||||||
|
import org.mariotaku.querybuilder.Expression;
|
||||||
import org.mariotaku.querybuilder.RawItemArray;
|
import org.mariotaku.querybuilder.RawItemArray;
|
||||||
import org.mariotaku.querybuilder.Where;
|
|
||||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||||
|
|
||||||
|
@ -39,18 +39,18 @@ import java.util.List;
|
||||||
import static org.mariotaku.twidere.util.Utils.isOfficialConsumerKeySecret;
|
import static org.mariotaku.twidere.util.Utils.isOfficialConsumerKeySecret;
|
||||||
import static org.mariotaku.twidere.util.Utils.shouldForceUsingPrivateAPIs;
|
import static org.mariotaku.twidere.util.Utils.shouldForceUsingPrivateAPIs;
|
||||||
|
|
||||||
public class Account implements Parcelable {
|
public class ParcelableAccount implements Parcelable {
|
||||||
|
|
||||||
public static final Parcelable.Creator<Account> CREATOR = new Parcelable.Creator<Account>() {
|
public static final Parcelable.Creator<ParcelableAccount> CREATOR = new Parcelable.Creator<ParcelableAccount>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account createFromParcel(final Parcel in) {
|
public ParcelableAccount createFromParcel(final Parcel in) {
|
||||||
return new Account(in);
|
return new ParcelableAccount(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account[] newArray(final int size) {
|
public ParcelableAccount[] newArray(final int size) {
|
||||||
return new Account[size];
|
return new ParcelableAccount[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class Account implements Parcelable {
|
||||||
public final boolean is_activated;
|
public final boolean is_activated;
|
||||||
public final boolean is_dummy;
|
public final boolean is_dummy;
|
||||||
|
|
||||||
public Account(final Cursor cursor, final Indices indices) {
|
public ParcelableAccount(final Cursor cursor, final Indices indices) {
|
||||||
is_dummy = false;
|
is_dummy = false;
|
||||||
screen_name = indices.screen_name != -1 ? cursor.getString(indices.screen_name) : null;
|
screen_name = indices.screen_name != -1 ? cursor.getString(indices.screen_name) : null;
|
||||||
name = indices.name != -1 ? cursor.getString(indices.name) : null;
|
name = indices.name != -1 ? cursor.getString(indices.name) : null;
|
||||||
|
@ -71,7 +71,7 @@ public class Account implements Parcelable {
|
||||||
is_activated = indices.is_activated != -1 && cursor.getInt(indices.is_activated) == 1;
|
is_activated = indices.is_activated != -1 && cursor.getInt(indices.is_activated) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account(final Parcel source) {
|
public ParcelableAccount(final Parcel source) {
|
||||||
is_dummy = source.readInt() == 1;
|
is_dummy = source.readInt() == 1;
|
||||||
is_activated = source.readInt() == 1;
|
is_activated = source.readInt() == 1;
|
||||||
account_id = source.readLong();
|
account_id = source.readLong();
|
||||||
|
@ -82,7 +82,7 @@ public class Account implements Parcelable {
|
||||||
color = source.readInt();
|
color = source.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account() {
|
private ParcelableAccount() {
|
||||||
is_dummy = true;
|
is_dummy = true;
|
||||||
screen_name = null;
|
screen_name = null;
|
||||||
name = null;
|
name = null;
|
||||||
|
@ -117,11 +117,11 @@ public class Account implements Parcelable {
|
||||||
out.writeInt(color);
|
out.writeInt(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account dummyInstance() {
|
public static ParcelableAccount dummyInstance() {
|
||||||
return new Account();
|
return new ParcelableAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account getAccount(final Context context, final long account_id) {
|
public static ParcelableAccount getAccount(final Context context, final long account_id) {
|
||||||
if (context == null) return null;
|
if (context == null) return null;
|
||||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
||||||
Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null);
|
Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null);
|
||||||
|
@ -130,7 +130,7 @@ public class Account implements Parcelable {
|
||||||
if (cur.getCount() > 0 && cur.moveToFirst()) {
|
if (cur.getCount() > 0 && cur.moveToFirst()) {
|
||||||
final Indices indices = new Indices(cur);
|
final Indices indices = new Indices(cur);
|
||||||
cur.moveToFirst();
|
cur.moveToFirst();
|
||||||
return new Account(cur, indices);
|
return new ParcelableAccount(cur, indices);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
cur.close();
|
cur.close();
|
||||||
|
@ -139,7 +139,7 @@ public class Account implements Parcelable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long[] getAccountIds(final Account[] accounts) {
|
public static long[] getAccountIds(final ParcelableAccount[] accounts) {
|
||||||
final long[] ids = new long[accounts.length];
|
final long[] ids = new long[accounts.length];
|
||||||
for (int i = 0, j = accounts.length; i < j; i++) {
|
for (int i = 0, j = accounts.length; i < j; i++) {
|
||||||
ids[i] = accounts[i].account_id;
|
ids[i] = accounts[i].account_id;
|
||||||
|
@ -147,25 +147,25 @@ public class Account implements Parcelable {
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account[] getAccounts(final Context context, final boolean activatedOnly,
|
public static ParcelableAccount[] getAccounts(final Context context, final boolean activatedOnly,
|
||||||
final boolean officialKeyOnly) {
|
final boolean officialKeyOnly) {
|
||||||
final List<Account> list = getAccountsList(context, activatedOnly, officialKeyOnly);
|
final List<ParcelableAccount> list = getAccountsList(context, activatedOnly, officialKeyOnly);
|
||||||
return list.toArray(new Account[list.size()]);
|
return list.toArray(new ParcelableAccount[list.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account[] getAccounts(final Context context, final long[] accountIds) {
|
public static ParcelableAccount[] getAccounts(final Context context, final long[] accountIds) {
|
||||||
if (context == null) return new Account[0];
|
if (context == null) return new ParcelableAccount[0];
|
||||||
final String where = accountIds != null ? Where.in(new Column(Accounts.ACCOUNT_ID),
|
final String where = accountIds != null ? Expression.in(new Column(Accounts.ACCOUNT_ID),
|
||||||
new RawItemArray(accountIds)).getSQL() : null;
|
new RawItemArray(accountIds)).getSQL() : null;
|
||||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
||||||
Accounts.COLUMNS_NO_CREDENTIALS, where, null, null);
|
Accounts.COLUMNS_NO_CREDENTIALS, where, null, null);
|
||||||
if (cur == null) return new Account[0];
|
if (cur == null) return new ParcelableAccount[0];
|
||||||
try {
|
try {
|
||||||
final Indices idx = new Indices(cur);
|
final Indices idx = new Indices(cur);
|
||||||
cur.moveToFirst();
|
cur.moveToFirst();
|
||||||
final Account[] names = new Account[cur.getCount()];
|
final ParcelableAccount[] names = new ParcelableAccount[cur.getCount()];
|
||||||
while (!cur.isAfterLast()) {
|
while (!cur.isAfterLast()) {
|
||||||
names[cur.getPosition()] = new Account(cur, idx);
|
names[cur.getPosition()] = new ParcelableAccount(cur, idx);
|
||||||
cur.moveToNext();
|
cur.moveToNext();
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
|
@ -174,14 +174,14 @@ public class Account implements Parcelable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Account> getAccountsList(final Context context, final boolean activatedOnly) {
|
public static List<ParcelableAccount> getAccountsList(final Context context, final boolean activatedOnly) {
|
||||||
return getAccountsList(context, activatedOnly, false);
|
return getAccountsList(context, activatedOnly, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Account> getAccountsList(final Context context, final boolean activatedOnly,
|
public static List<ParcelableAccount> getAccountsList(final Context context, final boolean activatedOnly,
|
||||||
final boolean officialKeyOnly) {
|
final boolean officialKeyOnly) {
|
||||||
if (context == null) return Collections.emptyList();
|
if (context == null) return Collections.emptyList();
|
||||||
final ArrayList<Account> accounts = new ArrayList<>();
|
final ArrayList<ParcelableAccount> accounts = new ArrayList<>();
|
||||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(),
|
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(),
|
||||||
Accounts.CONTENT_URI, Accounts.COLUMNS_NO_CREDENTIALS,
|
Accounts.CONTENT_URI, Accounts.COLUMNS_NO_CREDENTIALS,
|
||||||
activatedOnly ? Accounts.IS_ACTIVATED + " = 1" : null, null, Accounts.SORT_POSITION);
|
activatedOnly ? Accounts.IS_ACTIVATED + " = 1" : null, null, Accounts.SORT_POSITION);
|
||||||
|
@ -190,13 +190,13 @@ public class Account implements Parcelable {
|
||||||
cur.moveToFirst();
|
cur.moveToFirst();
|
||||||
while (!cur.isAfterLast()) {
|
while (!cur.isAfterLast()) {
|
||||||
if (!officialKeyOnly) {
|
if (!officialKeyOnly) {
|
||||||
accounts.add(new Account(cur, indices));
|
accounts.add(new ParcelableAccount(cur, indices));
|
||||||
} else {
|
} else {
|
||||||
final String consumerKey = cur.getString(indices.consumer_key);
|
final String consumerKey = cur.getString(indices.consumer_key);
|
||||||
final String consumerSecret = cur.getString(indices.consumer_secret);
|
final String consumerSecret = cur.getString(indices.consumer_secret);
|
||||||
if (shouldForceUsingPrivateAPIs(context)
|
if (shouldForceUsingPrivateAPIs(context)
|
||||||
|| isOfficialConsumerKeySecret(context, consumerKey, consumerSecret)) {
|
|| isOfficialConsumerKeySecret(context, consumerKey, consumerSecret)) {
|
||||||
accounts.add(new Account(cur, indices));
|
accounts.add(new ParcelableAccount(cur, indices));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur.moveToNext();
|
cur.moveToNext();
|
||||||
|
@ -205,7 +205,7 @@ public class Account implements Parcelable {
|
||||||
return accounts;
|
return accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AccountWithCredentials getAccountWithCredentials(final Context context, final long account_id) {
|
public static ParcelableAccountWithCredentials getAccountWithCredentials(final Context context, final long account_id) {
|
||||||
if (context == null) return null;
|
if (context == null) return null;
|
||||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,
|
||||||
Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null);
|
Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null);
|
||||||
|
@ -214,7 +214,7 @@ public class Account implements Parcelable {
|
||||||
if (cur.getCount() > 0 && cur.moveToFirst()) {
|
if (cur.getCount() > 0 && cur.moveToFirst()) {
|
||||||
final Indices indices = new Indices(cur);
|
final Indices indices = new Indices(cur);
|
||||||
cur.moveToFirst();
|
cur.moveToFirst();
|
||||||
return new AccountWithCredentials(cur, indices);
|
return new ParcelableAccountWithCredentials(cur, indices);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
cur.close();
|
cur.close();
|
||||||
|
@ -223,7 +223,7 @@ public class Account implements Parcelable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AccountWithCredentials extends Account {
|
public static class ParcelableAccountWithCredentials extends ParcelableAccount {
|
||||||
|
|
||||||
public final int auth_type;
|
public final int auth_type;
|
||||||
public final String consumer_key, consumer_secret;
|
public final String consumer_key, consumer_secret;
|
||||||
|
@ -232,7 +232,7 @@ public class Account implements Parcelable {
|
||||||
public final String api_url_format;
|
public final String api_url_format;
|
||||||
public final boolean same_oauth_signing_url, no_version_suffix;
|
public final boolean same_oauth_signing_url, no_version_suffix;
|
||||||
|
|
||||||
public AccountWithCredentials(final Cursor cursor, final Indices indices) {
|
public ParcelableAccountWithCredentials(final Cursor cursor, final Indices indices) {
|
||||||
super(cursor, indices);
|
super(cursor, indices);
|
||||||
auth_type = cursor.getInt(indices.auth_type);
|
auth_type = cursor.getInt(indices.auth_type);
|
||||||
consumer_key = cursor.getString(indices.consumer_key);
|
consumer_key = cursor.getString(indices.consumer_key);
|
||||||
|
@ -254,7 +254,7 @@ public class Account implements Parcelable {
|
||||||
+ ", api_url_format=" + api_url_format + ", same_oauth_signing_url=" + same_oauth_signing_url + "}";
|
+ ", api_url_format=" + api_url_format + ", same_oauth_signing_url=" + same_oauth_signing_url + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isOfficialCredentials(final Context context, final AccountWithCredentials account) {
|
public static boolean isOfficialCredentials(final Context context, final ParcelableAccountWithCredentials account) {
|
||||||
if (account == null) return false;
|
if (account == null) return false;
|
||||||
final boolean isOAuth = account.auth_type == Accounts.AUTH_TYPE_OAUTH
|
final boolean isOAuth = account.auth_type == Accounts.AUTH_TYPE_OAUTH
|
||||||
|| account.auth_type == Accounts.AUTH_TYPE_XAUTH;
|
|| account.auth_type == Accounts.AUTH_TYPE_XAUTH;
|
|
@ -39,7 +39,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public final Account[] accounts;
|
public final ParcelableAccount[] accounts;
|
||||||
public final ParcelableMediaUpdate[] media;
|
public final ParcelableMediaUpdate[] media;
|
||||||
public final String text;
|
public final String text;
|
||||||
public final ParcelableLocation location;
|
public final ParcelableLocation location;
|
||||||
|
@ -51,7 +51,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
* <b>ParcelableStatusUpdate.Builder</b> instead.
|
* <b>ParcelableStatusUpdate.Builder</b> instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public ParcelableStatusUpdate(final Account[] accounts, final String text, final ParcelableLocation location,
|
public ParcelableStatusUpdate(final ParcelableAccount[] accounts, final String text, final ParcelableLocation location,
|
||||||
final ParcelableMediaUpdate[] media, final long in_reply_to_status_id, final boolean is_possibly_sensitive) {
|
final ParcelableMediaUpdate[] media, final long in_reply_to_status_id, final boolean is_possibly_sensitive) {
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
@ -62,7 +62,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParcelableStatusUpdate(final Context context, final DraftItem draft) {
|
public ParcelableStatusUpdate(final Context context, final DraftItem draft) {
|
||||||
accounts = Account.getAccounts(context, draft.account_ids);
|
accounts = ParcelableAccount.getAccounts(context, draft.account_ids);
|
||||||
text = draft.text;
|
text = draft.text;
|
||||||
location = draft.location;
|
location = draft.location;
|
||||||
media = draft.media;
|
media = draft.media;
|
||||||
|
@ -71,7 +71,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParcelableStatusUpdate(final Parcel in) {
|
public ParcelableStatusUpdate(final Parcel in) {
|
||||||
accounts = in.createTypedArray(Account.CREATOR);
|
accounts = in.createTypedArray(ParcelableAccount.CREATOR);
|
||||||
text = in.readString();
|
text = in.readString();
|
||||||
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
|
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
|
||||||
media = in.createTypedArray(ParcelableMediaUpdate.CREATOR);
|
media = in.createTypedArray(ParcelableMediaUpdate.CREATOR);
|
||||||
|
@ -103,7 +103,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private Account[] accounts;
|
private ParcelableAccount[] accounts;
|
||||||
private String text;
|
private String text;
|
||||||
private ParcelableLocation location;
|
private ParcelableLocation location;
|
||||||
private ParcelableMediaUpdate[] media;
|
private ParcelableMediaUpdate[] media;
|
||||||
|
@ -123,7 +123,7 @@ public class ParcelableStatusUpdate implements Parcelable {
|
||||||
isPossiblySensitive(base.is_possibly_sensitive);
|
isPossiblySensitive(base.is_possibly_sensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder accounts(final Account[] accounts) {
|
public Builder accounts(final ParcelableAccount[] accounts) {
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,6 @@ import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ImageView.ScaleType;
|
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -47,7 +45,7 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
import org.mariotaku.twidere.task.AsyncTask;
|
import org.mariotaku.twidere.task.AsyncTask;
|
||||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||||
import org.mariotaku.twidere.util.Utils;
|
import org.mariotaku.twidere.util.Utils;
|
||||||
|
@ -76,9 +74,9 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccountsData(final List<Account> accounts) {
|
public void setAccountsData(final List<ParcelableAccount> accounts) {
|
||||||
removeAll();
|
removeAll();
|
||||||
for (final Account account : accounts) {
|
for (final ParcelableAccount account : accounts) {
|
||||||
final AccountItemPreference preference = new AccountItemPreference(getContext(), account, mSwitchKey,
|
final AccountItemPreference preference = new AccountItemPreference(getContext(), account, mSwitchKey,
|
||||||
mSwitchDefault);
|
mSwitchDefault);
|
||||||
setupPreference(preference, account);
|
setupPreference(preference, account);
|
||||||
|
@ -95,12 +93,12 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
||||||
new LoadAccountsTask(this).execute();
|
new LoadAccountsTask(this).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void setupPreference(AccountItemPreference preference, Account account);
|
protected abstract void setupPreference(AccountItemPreference preference, ParcelableAccount account);
|
||||||
|
|
||||||
public static final class AccountItemPreference extends Preference implements ImageLoadingListener,
|
public static final class AccountItemPreference extends Preference implements ImageLoadingListener,
|
||||||
OnCheckedChangeListener, OnSharedPreferenceChangeListener, OnPreferenceClickListener, OnClickListener {
|
OnCheckedChangeListener, OnSharedPreferenceChangeListener, OnPreferenceClickListener, OnClickListener {
|
||||||
|
|
||||||
private final Account mAccount;
|
private final ParcelableAccount mAccount;
|
||||||
private final SharedPreferences mSwitchPreference;
|
private final SharedPreferences mSwitchPreference;
|
||||||
private final ImageLoaderWrapper mImageLoader;
|
private final ImageLoaderWrapper mImageLoader;
|
||||||
|
|
||||||
|
@ -108,7 +106,7 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
||||||
private final boolean mSwitchDefault;
|
private final boolean mSwitchDefault;
|
||||||
private Switch mToggle;
|
private Switch mToggle;
|
||||||
|
|
||||||
public AccountItemPreference(final Context context, final Account account, final String switchKey,
|
public AccountItemPreference(final Context context, final ParcelableAccount account, final String switchKey,
|
||||||
final boolean switchDefault) {
|
final boolean switchDefault) {
|
||||||
super(context);
|
super(context);
|
||||||
setWidgetLayoutResource(R.layout.preference_widget_account_preference_item);
|
setWidgetLayoutResource(R.layout.preference_widget_account_preference_item);
|
||||||
|
@ -215,7 +213,7 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LoadAccountsTask extends AsyncTask<Void, Void, List<Account>> {
|
private static class LoadAccountsTask extends AsyncTask<Void, Void, List<ParcelableAccount>> {
|
||||||
|
|
||||||
private final AccountsListPreference mPreference;
|
private final AccountsListPreference mPreference;
|
||||||
|
|
||||||
|
@ -224,12 +222,12 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Account> doInBackground(final Void... params) {
|
protected List<ParcelableAccount> doInBackground(final Void... params) {
|
||||||
return Account.getAccountsList(mPreference.getContext(), false);
|
return ParcelableAccount.getAccountsList(mPreference.getContext(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(final List<Account> result) {
|
protected void onPostExecute(final List<ParcelableAccount> result) {
|
||||||
mPreference.setAccountsData(result);
|
mPreference.setAccountsData(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.mariotaku.twidere.TwidereConstants;
|
import org.mariotaku.twidere.TwidereConstants;
|
||||||
import org.mariotaku.twidere.fragment.AccountRefreshSettingsFragment;
|
import org.mariotaku.twidere.fragment.AccountRefreshSettingsFragment;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
|
|
||||||
public class AutoRefreshAccountsListPreference extends AccountsListPreference implements TwidereConstants {
|
public class AutoRefreshAccountsListPreference extends AccountsListPreference implements TwidereConstants {
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class AutoRefreshAccountsListPreference extends AccountsListPreference im
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupPreference(final AccountItemPreference preference, final Account account) {
|
protected void setupPreference(final AccountItemPreference preference, final ParcelableAccount account) {
|
||||||
preference.setFragment(AccountRefreshSettingsFragment.class.getName());
|
preference.setFragment(AccountRefreshSettingsFragment.class.getName());
|
||||||
final Bundle args = preference.getExtras();
|
final Bundle args = preference.getExtras();
|
||||||
args.putParcelable(EXTRA_ACCOUNT, account);
|
args.putParcelable(EXTRA_ACCOUNT, account);
|
||||||
|
|
|
@ -25,7 +25,7 @@ import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.mariotaku.twidere.TwidereConstants;
|
import org.mariotaku.twidere.TwidereConstants;
|
||||||
import org.mariotaku.twidere.fragment.AccountNotificationSettingsFragment;
|
import org.mariotaku.twidere.fragment.AccountNotificationSettingsFragment;
|
||||||
import org.mariotaku.twidere.model.Account;
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||||
|
|
||||||
public class NotificationAccountsListPreference extends AccountsListPreference implements TwidereConstants {
|
public class NotificationAccountsListPreference extends AccountsListPreference implements TwidereConstants {
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class NotificationAccountsListPreference extends AccountsListPreference i
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupPreference(final AccountItemPreference preference, final Account account) {
|
protected void setupPreference(final AccountItemPreference preference, final ParcelableAccount account) {
|
||||||
preference.setFragment(AccountNotificationSettingsFragment.class.getName());
|
preference.setFragment(AccountNotificationSettingsFragment.class.getName());
|
||||||
final Bundle args = preference.getExtras();
|
final Bundle args = preference.getExtras();
|
||||||
args.putParcelable(EXTRA_ACCOUNT, account);
|
args.putParcelable(EXTRA_ACCOUNT, account);
|
||||||
|
|
|
@ -146,7 +146,7 @@ public class TwidereCommandProvider extends ContentProvider implements Constants
|
||||||
case CODE_REFRESH_HOME_TIMELINE:
|
case CODE_REFRESH_HOME_TIMELINE:
|
||||||
if (mTwitterWrapper.isHomeTimelineRefreshing()) return getEmptyCursor();
|
if (mTwitterWrapper.isHomeTimelineRefreshing()) return getEmptyCursor();
|
||||||
case CODE_REFRESH_MENTIONS:
|
case CODE_REFRESH_MENTIONS:
|
||||||
if (mTwitterWrapper.isMentionsRefreshing()) return getEmptyCursor();
|
if (mTwitterWrapper.isMentionsTimelineRefreshing()) return getEmptyCursor();
|
||||||
case CODE_REFRESH_INBOX:
|
case CODE_REFRESH_INBOX:
|
||||||
if (mTwitterWrapper.isReceivedDirectMessagesRefreshing()) return getEmptyCursor();
|
if (mTwitterWrapper.isReceivedDirectMessagesRefreshing()) return getEmptyCursor();
|
||||||
case CODE_REFRESH_OUTBOX:
|
case CODE_REFRESH_OUTBOX:
|
||||||
|
|
|
@ -591,7 +591,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||||
isAccountSpecific = true;
|
isAccountSpecific = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NOTIFICATION_ID_MENTIONS: {
|
case NOTIFICATION_ID_MENTIONS_TIMELINE: {
|
||||||
mNewMentions.clear();
|
mNewMentions.clear();
|
||||||
isAccountSpecific = true;
|
isAccountSpecific = true;
|
||||||
break;
|
break;
|
||||||
|
@ -889,7 +889,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||||
private Cursor getNotificationsCursor() {
|
private Cursor getNotificationsCursor() {
|
||||||
final MatrixCursor c = new MatrixCursor(TweetStore.Notifications.MATRIX_COLUMNS);
|
final MatrixCursor c = new MatrixCursor(TweetStore.Notifications.MATRIX_COLUMNS);
|
||||||
c.addRow(new Integer[]{NOTIFICATION_ID_HOME_TIMELINE, mUnreadStatuses.size()});
|
c.addRow(new Integer[]{NOTIFICATION_ID_HOME_TIMELINE, mUnreadStatuses.size()});
|
||||||
c.addRow(new Integer[]{NOTIFICATION_ID_MENTIONS, mNewMentions.size()});
|
c.addRow(new Integer[]{NOTIFICATION_ID_MENTIONS_TIMELINE, mNewMentions.size()});
|
||||||
c.addRow(new Integer[]{NOTIFICATION_ID_DIRECT_MESSAGES, mNewMessages.size()});
|
c.addRow(new Integer[]{NOTIFICATION_ID_DIRECT_MESSAGES, mNewMessages.size()});
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -898,7 +898,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||||
final MatrixCursor c = new MatrixCursor(TweetStore.Notifications.MATRIX_COLUMNS);
|
final MatrixCursor c = new MatrixCursor(TweetStore.Notifications.MATRIX_COLUMNS);
|
||||||
if (id == NOTIFICATION_ID_HOME_TIMELINE) {
|
if (id == NOTIFICATION_ID_HOME_TIMELINE) {
|
||||||
c.addRow(new Integer[]{id, mNewStatuses.size()});
|
c.addRow(new Integer[]{id, mNewStatuses.size()});
|
||||||
} else if (id == NOTIFICATION_ID_MENTIONS) {
|
} else if (id == NOTIFICATION_ID_MENTIONS_TIMELINE) {
|
||||||
c.addRow(new Integer[]{id, mNewMentions.size()});
|
c.addRow(new Integer[]{id, mNewMentions.size()});
|
||||||
} else if (id == NOTIFICATION_ID_DIRECT_MESSAGES) {
|
} else if (id == NOTIFICATION_ID_DIRECT_MESSAGES) {
|
||||||
c.addRow(new Integer[]{id, mNewMessages.size()});
|
c.addRow(new Integer[]{id, mNewMessages.size()});
|
||||||
|
@ -1018,7 +1018,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||||
if (values == null || values.length == 0) return 0;
|
if (values == null || values.length == 0) return 0;
|
||||||
// Add statuses that not filtered to list for future use.
|
// Add statuses that not filtered to list for future use.
|
||||||
int result = 0;
|
int result = 0;
|
||||||
final boolean enabled = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS, true);
|
final boolean enabled = mPreferences.getBoolean(KEY_FILTERS_IN_MENTIONS_TIMELINE, true);
|
||||||
final boolean filtersForRts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
|
final boolean filtersForRts = mPreferences.getBoolean(KEY_FILTERS_FOR_RTS, true);
|
||||||
for (final ContentValues value : values) {
|
for (final ContentValues value : values) {
|
||||||
final ParcelableStatus status = new ParcelableStatus(value);
|
final ParcelableStatus status = new ParcelableStatus(value);
|
||||||
|
@ -1112,12 +1112,12 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||||
if (pref.isMentionsNotificationEnabled()) {
|
if (pref.isMentionsNotificationEnabled()) {
|
||||||
final long accountId = pref.getAccountId();
|
final long accountId = pref.getAccountId();
|
||||||
displayStatusesNotification(notifiedCount, pref, pref.getMentionsNotificationType(),
|
displayStatusesNotification(notifiedCount, pref, pref.getMentionsNotificationType(),
|
||||||
NOTIFICATION_ID_MENTIONS, getStatusesForAccounts(items, accountId),
|
NOTIFICATION_ID_MENTIONS_TIMELINE, getStatusesForAccounts(items, accountId),
|
||||||
R.string.notification_mention, R.string.notification_mention_multiple,
|
R.string.notification_mention, R.string.notification_mention_multiple,
|
||||||
R.drawable.ic_stat_mention);
|
R.drawable.ic_stat_mention);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyUnreadCountChanged(NOTIFICATION_ID_MENTIONS);
|
notifyUnreadCountChanged(NOTIFICATION_ID_MENTIONS_TIMELINE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TABLE_ID_DIRECT_MESSAGES_INBOX: {
|
case TABLE_ID_DIRECT_MESSAGES_INBOX: {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue