diff --git a/resources/ic_user_type_protected.png b/resources/ic_user_type_protected.png new file mode 100644 index 000000000..34f11cfb6 Binary files /dev/null and b/resources/ic_user_type_protected.png differ diff --git a/resources/ic_user_type_verified.png b/resources/ic_user_type_verified.png index d4c3f7d22..c44eff6e6 100755 Binary files a/resources/ic_user_type_verified.png and b/resources/ic_user_type_verified.png differ diff --git a/twidere/build.gradle b/twidere/build.gradle index 3f58a78b7..3c11d4be6 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -83,7 +83,6 @@ dependencies { compile 'com.android.support:cardview-v7:21.0.2' compile 'com.android.support:recyclerview-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 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5' compile 'com.twitter:twitter-text:1.9.9' diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/AllColumns.java b/twidere/src/main/java/org/mariotaku/querybuilder/AllColumns.java index 0aab0172d..838fcba9b 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/AllColumns.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/AllColumns.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,19 +29,19 @@ package org.mariotaku.querybuilder; public class AllColumns implements Selectable { - private final String table; + private final String table; - public AllColumns() { - this(null); - } + public AllColumns() { + this(null); + } - public AllColumns(final String table) { - this.table = table; - } + public AllColumns(final String table) { + this.table = table; + } - @Override - public String getSQL() { - return table != null ? table + ".*" : "*"; - } + @Override + public String getSQL() { + return table != null ? table + ".*" : "*"; + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Columns.java b/twidere/src/main/java/org/mariotaku/querybuilder/Columns.java index 858cb2fbb..fcc485036 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/Columns.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Columns.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,64 +29,81 @@ package org.mariotaku.querybuilder; public class Columns implements Selectable { - private final AbsColumn[] columns; + private final AbsColumn[] columns; - public Columns(final AbsColumn... columns) { - this.columns = columns; - } + public Columns(String... columns) { + this(Columns.fromStrings(columns)); + } - @Override - public String getSQL() { - return Utils.toString(columns); - } + public Columns(final AbsColumn... columns) { + this.columns = 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() { - this(null); - } + public static class AllColumn extends AbsColumn { - public AllColumn(final String table) { - this.table = table; - } + private final Table table; - @Override - public String getSQL() { - return table != null ? table + ".*" : "*"; - } + public AllColumn() { + this(null); + } - } + 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) { - this(null, columnName, null); - } + public static class Column extends AbsColumn { - public Column(final String columnName, final String alias) { - this(null, columnName, alias); - } + private final Table table; + private final String columnName, alias; - public Column(final String table, final String columnName, final String alias) { - if (columnName == null) throw new IllegalArgumentException(""); - this.table = table; - this.columnName = columnName; - this.alias = alias; - } + public Column(final String columnName) { + this(null, columnName, null); + } - @Override - public String getSQL() { - final String col = table != null ? table + "." + columnName : columnName; - return alias != null ? col + " AS " + alias : col; - } - } + public Column(final String columnName, final String alias) { + this(null, columnName, alias); + } + + 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; + } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Expression.java b/twidere/src/main/java/org/mariotaku/querybuilder/Expression.java new file mode 100644 index 000000000..12b183ab5 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Expression.java @@ -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 + */ + +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; + } +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/NewColumn.java b/twidere/src/main/java/org/mariotaku/querybuilder/NewColumn.java index 266f24cec..c1fe99a62 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/NewColumn.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/NewColumn.java @@ -2,36 +2,37 @@ package org.mariotaku.querybuilder; public class NewColumn implements SQLLang { - private final String name; - private final String type; + private final String name; + private final String type; - public NewColumn(final String name, final String type) { - this.name = name; - this.type = type; - } + public NewColumn(final String name, final String type) { + this.name = name; + this.type = type; + } - public String getName() { - return name; - } + public static NewColumn[] createNewColumns(final String[] colNames, final String[] colTypes) { + 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 getSQL() { - if (name == null || type == null) throw new NullPointerException("name and type must not be null!"); - return String.format("%s %s", name, type); - } + public String getName() { + return name; + } - public String getType() { - return type; - } + @Override + 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) { - 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; - } + public String getType() { + return type; + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/OnConflict.java b/twidere/src/main/java/org/mariotaku/querybuilder/OnConflict.java new file mode 100644 index 000000000..6c9b638a3 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/OnConflict.java @@ -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; + } +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/OrderBy.java b/twidere/src/main/java/org/mariotaku/querybuilder/OrderBy.java index f7c5096db..d593d5036 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/OrderBy.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/OrderBy.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,25 +21,26 @@ * 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 */ package org.mariotaku.querybuilder; + import org.mariotaku.twidere.util.ArrayUtils; public class OrderBy implements SQLLang { - private final String[] orderBy; + private final String[] orderBy; - public OrderBy(final String... orderBy) { - this.orderBy = orderBy; - } + public OrderBy(final String... orderBy) { + this.orderBy = orderBy; + } - @Override - public String getSQL() { - return ArrayUtils.toString(orderBy, ',', false); - } + @Override + public String getSQL() { + return ArrayUtils.toString(orderBy, ',', false); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/RawItemArray.java b/twidere/src/main/java/org/mariotaku/querybuilder/RawItemArray.java index 5fbd410d5..648e8a45d 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/RawItemArray.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/RawItemArray.java @@ -2,23 +2,23 @@ package org.mariotaku.querybuilder; public class RawItemArray implements Selectable { - private final Object[] array; + private final Object[] array; - public RawItemArray(final long[] array) { - final Long[] converted = new Long[array.length]; - for (int i = 0, j = array.length; i < j; i++) { - converted[i] = array[i]; - } - this.array = converted; - } + public RawItemArray(final long[] array) { + final Long[] converted = new Long[array.length]; + for (int i = 0, j = array.length; i < j; i++) { + converted[i] = array[i]; + } + this.array = converted; + } - public RawItemArray(final Object[] array) { - this.array = array; - } + public RawItemArray(final String[] array) { + this.array = array; + } - @Override - public String getSQL() { - return Utils.toString(array, ',', false); - } + @Override + public String getSQL() { + return Utils.toString(array, ',', false); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SQLFunctions.java b/twidere/src/main/java/org/mariotaku/querybuilder/SQLFunctions.java index 0d42e41ba..903018b06 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/SQLFunctions.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SQLFunctions.java @@ -2,8 +2,12 @@ package org.mariotaku.querybuilder; public class SQLFunctions { - public static String SUM(final String val) { - return String.format("SUM (%s)", val); - } + public static String SUM(final String val) { + return String.format("SUM (%s)", val); + } + + public static String COUNT(final String val) { + return String.format("COUNT (%s)", val); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SQLLang.java b/twidere/src/main/java/org/mariotaku/querybuilder/SQLLang.java index 4ad782d3d..de444fae6 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/SQLLang.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SQLLang.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,10 +29,10 @@ package org.mariotaku.querybuilder; public interface SQLLang extends Cloneable { - /** - * Build SQL query string - * - * @return SQL query - */ - public String getSQL(); + /** + * Build SQL query string + * + * @return SQL query + */ + public String getSQL(); } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SQLQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQuery.java new file mode 100644 index 000000000..7f64967b5 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQuery.java @@ -0,0 +1,7 @@ +package org.mariotaku.querybuilder; + +/** + * Created by mariotaku on 14-8-6. + */ +public interface SQLQuery extends SQLLang { +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryBuilder.java b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryBuilder.java index cf034ce12..5f00d7b44 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryBuilder.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryBuilder.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,70 +29,81 @@ package org.mariotaku.querybuilder; import org.mariotaku.querybuilder.query.SQLAlterTableQuery; import org.mariotaku.querybuilder.query.SQLCreateTableQuery; +import org.mariotaku.querybuilder.query.SQLCreateTriggerQuery; import org.mariotaku.querybuilder.query.SQLCreateViewQuery; import org.mariotaku.querybuilder.query.SQLDropTableQuery; +import org.mariotaku.querybuilder.query.SQLDropTriggerQuery; import org.mariotaku.querybuilder.query.SQLDropViewQuery; -import org.mariotaku.querybuilder.query.SQLInsertIntoQuery; -import org.mariotaku.querybuilder.query.SQLInsertIntoQuery.OnConflict; +import org.mariotaku.querybuilder.query.SQLInsertQuery; import org.mariotaku.querybuilder.query.SQLSelectQuery; public class SQLQueryBuilder { - private SQLQueryBuilder() { - throw new AssertionError("You can't create instance for this class"); - } + private SQLQueryBuilder() { + throw new AssertionError("You can't create instance for this class"); + } - public static SQLAlterTableQuery.Builder alterTable(final String table) { - return new SQLAlterTableQuery.Builder().alterTable(table); - } + public static SQLAlterTableQuery.Builder alterTable(final String table) { + return new SQLAlterTableQuery.Builder().alterTable(table); + } - public static SQLCreateTableQuery.Builder createTable(final boolean temporary, final boolean createIfNotExists, - final String name) { - return new SQLCreateTableQuery.Builder().createTable(temporary, createIfNotExists, name); - } + public static SQLCreateTableQuery.Builder createTable(final boolean temporary, final boolean createIfNotExists, + final String name) { + return new SQLCreateTableQuery.Builder().createTable(temporary, createIfNotExists, name); + } - public static SQLCreateTableQuery.Builder createTable(final boolean createIfNotExists, final String name) { - return createTable(false, createIfNotExists, name); - } + public static SQLCreateTableQuery.Builder createTable(final boolean createIfNotExists, final String name) { + return createTable(false, createIfNotExists, name); + } - public static SQLCreateTableQuery.Builder createTable(final String name) { - return createTable(false, false, name); - } + public static SQLCreateTableQuery.Builder createTable(final String name) { + return createTable(false, false, name); + } - public static SQLCreateViewQuery.Builder createView(final boolean temporary, final boolean createIfNotExists, - final String name) { - return new SQLCreateViewQuery.Builder().createView(temporary, createIfNotExists, name); - } + public static SQLCreateViewQuery.Builder createView(final boolean temporary, final boolean createIfNotExists, + final String 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) { - return createView(false, false, name); - } + public static SQLCreateTriggerQuery.Builder createTrigger(final boolean temporary, final boolean createIfNotExists, + final String name) { + return new SQLCreateTriggerQuery.Builder().createTrigger(temporary, createIfNotExists, name); + } - public static SQLDropTableQuery dropTable(final boolean dropIfExists, final String table) { - return new SQLDropTableQuery(dropIfExists, table); - } + public static SQLCreateViewQuery.Builder createView(final boolean createIfNotExists, final String name) { + return createView(false, createIfNotExists, name); + } - public static SQLDropViewQuery dropView(final boolean dropIfExists, final String table) { - return new SQLDropViewQuery(dropIfExists, table); - } + public static SQLCreateViewQuery.Builder createView(final String name) { + return createView(false, false, name); + } - public static SQLInsertIntoQuery.Builder insertInto(final OnConflict onConflict, final String table) { - return new SQLInsertIntoQuery.Builder().insertInto(onConflict, table); - } + public static SQLDropTableQuery dropTable(final boolean dropIfExists, final String table) { + return new SQLDropTableQuery(dropIfExists, table); + } - public static SQLInsertIntoQuery.Builder insertInto(final String table) { - return insertInto(null, table); - } + public static SQLDropViewQuery dropView(final boolean dropIfExists, final String table) { + return new SQLDropViewQuery(dropIfExists, table); + } - public static SQLSelectQuery.Builder select(final boolean distinct, final Selectable select) { - return new SQLSelectQuery.Builder().select(distinct, select); - } + public static SQLDropTriggerQuery dropTrigger(final boolean dropIfExists, final String table) { + return new SQLDropTriggerQuery(dropIfExists, table); + } - public static SQLSelectQuery.Builder select(final Selectable select) { - return select(false, select); - } + public static SQLInsertQuery.Builder insertInto(final OnConflict onConflict, final String table) { + 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); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryException.java b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryException.java index 619bd7158..829c7573f 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryException.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SQLQueryException.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,21 +29,21 @@ package org.mariotaku.querybuilder; 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) { - super(detailMessage); - } + public SQLQueryException(final String detailMessage) { + super(detailMessage); + } - public SQLQueryException(final String detailMessage, final Throwable throwable) { - super(detailMessage, throwable); - } + public SQLQueryException(final String detailMessage, final Throwable throwable) { + super(detailMessage, throwable); + } - public SQLQueryException(final Throwable throwable) { - super(throwable); - } + public SQLQueryException(final Throwable throwable) { + super(throwable); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Selectable.java b/twidere/src/main/java/org/mariotaku/querybuilder/Selectable.java index f7414cc9a..2a154572e 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/Selectable.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Selectable.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/SetValue.java b/twidere/src/main/java/org/mariotaku/querybuilder/SetValue.java new file mode 100644 index 000000000..d509f8a3b --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/SetValue.java @@ -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()); + } +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Table.java b/twidere/src/main/java/org/mariotaku/querybuilder/Table.java new file mode 100644 index 000000000..d224e1bfb --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Table.java @@ -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 + */ + +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; + } + +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Tables.java b/twidere/src/main/java/org/mariotaku/querybuilder/Tables.java index c214dad8b..f489979c0 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/Tables.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Tables.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,23 +21,24 @@ * 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 */ 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) { - this.tables = tables; - } + public Tables(final String... tables) { + super(null); + this.tables = tables; + } - @Override - public String getSQL() { - return Utils.toString(tables, ',', false); - } + @Override + public String getSQL() { + return Utils.toString(tables, ',', false); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Utils.java b/twidere/src/main/java/org/mariotaku/querybuilder/Utils.java index 246764b2f..c21568ce2 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/Utils.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/Utils.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,7 +21,7 @@ * 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 */ @@ -29,34 +29,25 @@ package org.mariotaku.querybuilder; public class Utils { - public static String toString(final Object[] array, final char token, final boolean include_space) { - final StringBuilder builder = new StringBuilder(); - final int length = array.length; - for (int i = 0; i < length; i++) { - final String id_string = String.valueOf(array[i]); - if (id_string != null) { - if (i > 0) { - builder.append(include_space ? token + " " : token); - } - builder.append(id_string); - } - } - return builder.toString(); - } + public static String toString(final Object[] array, final char token, final boolean includeSpace) { + final StringBuilder builder = new StringBuilder(); + final int length = array.length; + for (int i = 0; i < length; i++) { + final String string = objectToString(array[i]); + if (string != null) { + if (i > 0) { + builder.append(includeSpace ? token + " " : token); + } + builder.append(string); + } + } + return builder.toString(); + } - public static String toString(final SQLLang[] array) { - final StringBuilder builder = new StringBuilder(); - final int length = array.length; - for (int i = 0; i < length; i++) { - final String id_string = array[i].getSQL(); - if (id_string != null) { - if (i > 0) { - builder.append(", "); - } - builder.append(id_string); - } - } - return builder.toString(); - } + private static String objectToString(Object o) { + if (o instanceof SQLLang) + return ((SQLLang) o).getSQL(); + return o != null ? o.toString() : null; + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/Where.java b/twidere/src/main/java/org/mariotaku/querybuilder/Where.java deleted file mode 100644 index 6f395a0dd..000000000 --- a/twidere/src/main/java/org/mariotaku/querybuilder/Where.java +++ /dev/null @@ -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 - */ - -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(); - } -} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/IBuilder.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/IBuilder.java index fa65c3ff8..7bc31e6a4 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/IBuilder.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/IBuilder.java @@ -4,13 +4,13 @@ import org.mariotaku.querybuilder.SQLLang; public interface IBuilder { - public T build(); + public T build(); - /** - * Equivalent to {@link #build()}.{@link #SQLLang.getSQL()} - * - * @return - */ - public String buildSQL(); + /** + * Equivalent to {@link #build()}.{@link SQLLang#getSQL()} + * + * @return + */ + public String buildSQL(); } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLAlterTableQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLAlterTableQuery.java index 789aa82f3..a8aaa93ce 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLAlterTableQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLAlterTableQuery.java @@ -1,71 +1,70 @@ package org.mariotaku.querybuilder.query; 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 renameTo; - private NewColumn addColumn; + private String table; + private String renameTo; + private NewColumn addColumn; - @Override - public String getSQL() { - if (table == null) throw new NullPointerException("table must not be null!"); - if (renameTo == null && addColumn == null) throw new NullPointerException(); - 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()); - } + @Override + public String getSQL() { + if (table == null) throw new NullPointerException("table must not be null!"); + if (renameTo == null && addColumn == null) throw new NullPointerException(); + 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()); + } - void setAddColumn(final NewColumn addColumn) { - this.addColumn = addColumn; - } + void setAddColumn(final NewColumn addColumn) { + this.addColumn = addColumn; + } - void setRenameTo(final String renameTo) { - this.renameTo = renameTo; - } + void setRenameTo(final String renameTo) { + this.renameTo = renameTo; + } - void setTable(final String table) { - this.table = table; - } + void setTable(final String table) { + this.table = table; + } - public static final class Builder implements IBuilder { + public static final class Builder implements IBuilder { - 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) { - checkNotBuilt(); - query.setAddColumn(addColumn); - return this; - } + public Builder alterTable(final String table) { + checkNotBuilt(); + query.setTable(table); + return this; + } - public Builder alterTable(final String table) { - checkNotBuilt(); - query.setTable(table); - return this; - } + @Override + public SQLAlterTableQuery build() { + return query; + } - @Override - public SQLAlterTableQuery build() { - return query; - } + @Override + public String buildSQL() { + return build().getSQL(); + } - @Override - public String buildSQL() { - return build().getSQL(); - } + public Builder renameTo(final String renameTo) { + checkNotBuilt(); + query.setRenameTo(renameTo); + return this; + } - public Builder renameTo(final String renameTo) { - checkNotBuilt(); - query.setRenameTo(renameTo); - return this; - } - - private void checkNotBuilt() { - if (buildCalled) throw new IllegalStateException(); - } - } + private void checkNotBuilt() { + if (buildCalled) throw new IllegalStateException(); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTableQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTableQuery.java index ab6d8ce6f..f0610e380 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTableQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTableQuery.java @@ -1,111 +1,111 @@ package org.mariotaku.querybuilder.query; import org.mariotaku.querybuilder.NewColumn; -import org.mariotaku.querybuilder.SQLLang; +import org.mariotaku.querybuilder.SQLQuery; import org.mariotaku.querybuilder.Utils; -public class SQLCreateTableQuery implements SQLLang { +public class SQLCreateTableQuery implements SQLQuery { - private boolean temporary; - private boolean createIfNotExists; - private String table; - private NewColumn[] newColumns; - private SQLSelectQuery selectStmt; + private boolean temporary; + private boolean createIfNotExists; + private String table; + private NewColumn[] newColumns; + private SQLSelectQuery selectStmt; - SQLCreateTableQuery() { - } + SQLCreateTableQuery() { + } - @Override - public String getSQL() { - if (table == null) throw new NullPointerException("NAME must not be null!"); - if ((newColumns == null || newColumns.length == 0) && selectStmt == null) - throw new NullPointerException("Columns or AS must not be null!"); - final StringBuilder sb = new StringBuilder("CREATE "); - if (temporary) { - sb.append("TEMPORARY "); - } - sb.append("TABLE "); - if (createIfNotExists) { - sb.append("IF NOT EXISTS "); - } - sb.append(String.format("%s ", table)); - if (newColumns != null && newColumns.length > 0) { - sb.append(String.format("(%s)", Utils.toString(newColumns))); - } else { - sb.append(String.format("AS %s", selectStmt.getSQL())); - } - return sb.toString(); - } + @Override + public String getSQL() { + if (table == null) throw new NullPointerException("NAME must not be null!"); + if ((newColumns == null || newColumns.length == 0) && selectStmt == null) + throw new NullPointerException("Columns or AS must not be null!"); + final StringBuilder sb = new StringBuilder("CREATE "); + if (temporary) { + sb.append("TEMPORARY "); + } + sb.append("TABLE "); + if (createIfNotExists) { + sb.append("IF NOT EXISTS "); + } + sb.append(String.format("%s ", table)); + if (newColumns != null && newColumns.length > 0) { + sb.append(String.format("(%s)", Utils.toString(newColumns, ',', true))); + } else { + sb.append(String.format("AS %s", selectStmt.getSQL())); + } + return sb.toString(); + } - void setAs(final SQLSelectQuery selectStmt) { - this.selectStmt = selectStmt; - } + void setAs(final SQLSelectQuery selectStmt) { + this.selectStmt = selectStmt; + } - void setCreateIfNotExists(final boolean createIfNotExists) { - this.createIfNotExists = createIfNotExists; - } + void setCreateIfNotExists(final boolean createIfNotExists) { + this.createIfNotExists = createIfNotExists; + } - void setNewColumns(final NewColumn[] newColumns) { - this.newColumns = newColumns; - } + void setNewColumns(final NewColumn[] newColumns) { + this.newColumns = newColumns; + } - void setTable(final String table) { - this.table = table; - } + void setTable(final String table) { + this.table = table; + } - void setTemporary(final boolean temporary) { - this.temporary = temporary; - } + void setTemporary(final boolean temporary) { + this.temporary = temporary; + } - public static final class Builder implements IBuilder { + public static final class Builder implements IBuilder { - private final SQLCreateTableQuery query = new SQLCreateTableQuery(); + private final SQLCreateTableQuery query = new SQLCreateTableQuery(); - private boolean buildCalled; + private boolean buildCalled; - public Builder as(final SQLSelectQuery selectStmt) { - checkNotBuilt(); - query.setAs(selectStmt); - return this; - } + public Builder as(final SQLSelectQuery selectStmt) { + checkNotBuilt(); + query.setAs(selectStmt); + return this; + } - @Override - public SQLCreateTableQuery build() { - buildCalled = true; - return query; - } + @Override + public SQLCreateTableQuery build() { + buildCalled = true; + return query; + } - @Override - public String buildSQL() { - return build().getSQL(); - } + @Override + public String buildSQL() { + return build().getSQL(); + } - public Builder columns(final NewColumn... newColumns) { - checkNotBuilt(); - query.setNewColumns(newColumns); - return this; - } + public Builder columns(final NewColumn... newColumns) { + checkNotBuilt(); + query.setNewColumns(newColumns); + return this; + } - public Builder createTable(final boolean temporary, final boolean createIfNotExists, final String table) { - checkNotBuilt(); - query.setTemporary(temporary); - query.setCreateIfNotExists(createIfNotExists); - query.setTable(table); - return this; - } + public Builder createTable(final boolean temporary, final boolean createIfNotExists, final String table) { + checkNotBuilt(); + query.setTemporary(temporary); + query.setCreateIfNotExists(createIfNotExists); + query.setTable(table); + return this; + } - public Builder createTable(final boolean createIfNotExists, final String table) { - return createTable(false, createIfNotExists, table); - } + public Builder createTable(final boolean createIfNotExists, final String table) { + return createTable(false, createIfNotExists, table); + } - public Builder createTemporaryTable(final boolean createIfNotExists, final String table) { - return createTable(true, createIfNotExists, table); - } + public Builder createTemporaryTable(final boolean createIfNotExists, final String table) { + return createTable(true, createIfNotExists, table); + } - private void checkNotBuilt() { - if (buildCalled) throw new IllegalStateException(); - } + private void checkNotBuilt() { + if (buildCalled) throw new IllegalStateException(); + } - } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTriggerQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTriggerQuery.java new file mode 100644 index 000000000..00aa9c8e6 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateTriggerQuery.java @@ -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 { + + 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; + } + } +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateViewQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateViewQuery.java index b15285a1e..031dc5047 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateViewQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLCreateViewQuery.java @@ -1,90 +1,90 @@ 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 createIfNotExists; - private String name; - private SQLSelectQuery selectStmt; + private boolean temporary; + private boolean createIfNotExists; + private String name; + private SQLSelectQuery selectStmt; - SQLCreateViewQuery() { + SQLCreateViewQuery() { - } + } - @Override - public String getSQL() { - if (name == null) throw new NullPointerException("NAME must not be null!"); - if (selectStmt == null) throw new NullPointerException("SELECT statement must not be null!"); - final StringBuilder sb = new StringBuilder("CREATE "); - if (temporary) { - sb.append("TEMPORARY "); - } - sb.append("VIEW "); - if (createIfNotExists) { - sb.append("IF NOT EXISTS "); - } - sb.append(String.format("%s AS %s", name, selectStmt.getSQL())); - return sb.toString(); - } + @Override + public String getSQL() { + if (name == null) throw new NullPointerException("NAME must not be null!"); + if (selectStmt == null) + throw new NullPointerException("SELECT statement must not be null!"); + final StringBuilder sb = new StringBuilder("CREATE "); + if (temporary) { + sb.append("TEMPORARY "); + } + sb.append("VIEW "); + if (createIfNotExists) { + sb.append("IF NOT EXISTS "); + } + sb.append(String.format("%s AS %s", name, selectStmt.getSQL())); + return sb.toString(); + } - void setAs(final SQLSelectQuery selectStmt) { - this.selectStmt = selectStmt; - } + void setAs(final SQLSelectQuery selectStmt) { + this.selectStmt = selectStmt; + } - void setCreateIfNotExists(final boolean createIfNotExists) { - this.createIfNotExists = createIfNotExists; - } + void setCreateIfNotExists(final boolean createIfNotExists) { + this.createIfNotExists = createIfNotExists; + } - void setName(final String name) { - this.name = name; - } + void setName(final String name) { + this.name = name; + } - void setTemporary(final boolean temporary) { - this.temporary = temporary; - } + void setTemporary(final boolean temporary) { + this.temporary = temporary; + } - public static final class Builder implements IBuilder { + public static final class Builder implements IBuilder { - 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) { - checkNotBuilt(); - query.setAs(selectStmt); - return this; - } + @Override + public SQLCreateViewQuery build() { + return query; + } - @Override - public SQLCreateViewQuery build() { - return query; - } + @Override + public String buildSQL() { + return build().getSQL(); + } - @Override - public String buildSQL() { - return build().getSQL(); - } + public Builder createTemporaryView(final boolean createIfNotExists, final String name) { + return createView(true, createIfNotExists, name); + } - public Builder createTemporaryView(final boolean createIfNotExists, final String name) { - return createView(true, createIfNotExists, name); - } + public Builder createView(final boolean temporary, final boolean createIfNotExists, final String 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) { - checkNotBuilt(); - query.setTemporary(temporary); - query.setCreateIfNotExists(createIfNotExists); - query.setName(name); - return this; - } + public Builder createView(final boolean createIfNotExists, final String name) { + return createView(false, createIfNotExists, name); + } - public Builder createView(final boolean createIfNotExists, final String name) { - return createView(false, createIfNotExists, name); - } - - private void checkNotBuilt() { - if (buildCalled) throw new IllegalStateException(); - } - } + private void checkNotBuilt() { + if (buildCalled) throw new IllegalStateException(); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDeleteQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDeleteQuery.java index cf4862dd5..e187f04fa 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDeleteQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDeleteQuery.java @@ -1,57 +1,57 @@ package org.mariotaku.querybuilder.query; -import org.mariotaku.querybuilder.SQLLang; -import org.mariotaku.querybuilder.Where; +import org.mariotaku.querybuilder.Expression; +import org.mariotaku.querybuilder.SQLQuery; -public class SQLDeleteQuery implements SQLLang { +public class SQLDeleteQuery implements SQLQuery { - private String table; - private Where where; + private String table; + private Expression where; - @Override - public String getSQL() { - if (where != null) return String.format("DELETE FROM %s", table); - return String.format("DELETE FROM %S WHERE %s", table, where.getSQL()); - } + @Override + public String getSQL() { + if (where != null) return String.format("DELETE FROM %s", table); + return String.format("DELETE FROM %S WHERE %s", table, where.getSQL()); + } - void setFrom(final String table) { - this.table = table; - } + void setFrom(final String table) { + this.table = table; + } - void setWhere(final Where where) { - this.where = where; - } + void setWhere(final Expression where) { + this.where = where; + } - public static final class Builder implements IBuilder { - private boolean buildCalled; - private final SQLDeleteQuery query = new SQLDeleteQuery(); + public static final class Builder implements IBuilder { + private final SQLDeleteQuery query = new SQLDeleteQuery(); + private boolean buildCalled; - @Override - public SQLDeleteQuery build() { - buildCalled = true; - return query; - } + @Override + public SQLDeleteQuery build() { + buildCalled = true; + return query; + } - @Override - public String buildSQL() { - return build().getSQL(); - } + @Override + public String buildSQL() { + return build().getSQL(); + } - public Builder from(final String table) { - checkNotBuilt(); - query.setFrom(table); - return this; - } + public Builder from(final String table) { + checkNotBuilt(); + query.setFrom(table); + return this; + } - public Builder where(final Where where) { - checkNotBuilt(); - query.setWhere(where); - return this; - } + public Builder where(final Expression where) { + checkNotBuilt(); + query.setWhere(where); + return this; + } - private void checkNotBuilt() { - if (buildCalled) throw new IllegalStateException(); - } - } + private void checkNotBuilt() { + if (buildCalled) throw new IllegalStateException(); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropQuery.java index 6967baa49..021b0c5b3 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropQuery.java @@ -1,19 +1,24 @@ 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) { - if (table == null) throw new NullPointerException(); - this.table = table; - } + public SQLDropQuery(final boolean dropIfExists, final String type, final String target) { + if (target == null) throw new NullPointerException(); + this.dropIfExists = dropIfExists; + this.type = type; + this.target = target; + } - @Override - public String getSQL() { - return String.format("DROP TABLE %s", table); - } + @Override + public final String getSQL() { + if (dropIfExists) return String.format("DROP %s IF EXISTS %s", type, target); + return String.format("DROP %s %s", type, target); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTableQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTableQuery.java index 9053abafd..bd8486acd 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTableQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTableQuery.java @@ -1,22 +1,9 @@ package org.mariotaku.querybuilder.query; -import org.mariotaku.querybuilder.SQLLang; +public class SQLDropTableQuery extends SQLDropQuery { -public class SQLDropTableQuery implements SQLLang { - - 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); - } + public SQLDropTableQuery(final boolean dropIfExists, final String table) { + super(dropIfExists, "TABLE", table); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTriggerQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTriggerQuery.java new file mode 100644 index 000000000..b51e4f001 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropTriggerQuery.java @@ -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); + } + +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropViewQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropViewQuery.java index d6c460932..42c167234 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropViewQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLDropViewQuery.java @@ -1,22 +1,9 @@ package org.mariotaku.querybuilder.query; -import org.mariotaku.querybuilder.SQLLang; +public class SQLDropViewQuery extends SQLDropQuery { -public class SQLDropViewQuery implements SQLLang { - - 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); - } + public SQLDropViewQuery(final boolean dropIfExists, final String table) { + super(dropIfExists, "VIEW", table); + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertIntoQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertIntoQuery.java deleted file mode 100644 index a83faacd5..000000000 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertIntoQuery.java +++ /dev/null @@ -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 { - - 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; - } - } - -} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertQuery.java new file mode 100644 index 000000000..86510acee --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLInsertQuery.java @@ -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 { + + 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(); + } + + } + +} diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLSelectQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLSelectQuery.java index 2bc26ee92..438355b77 100644 --- a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLSelectQuery.java +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLSelectQuery.java @@ -1,11 +1,11 @@ /** * 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 @@ -21,240 +21,241 @@ * 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 */ package org.mariotaku.querybuilder.query; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.SQLLang; +import org.mariotaku.querybuilder.SQLQuery; import org.mariotaku.querybuilder.SQLQueryException; import org.mariotaku.querybuilder.Selectable; -import org.mariotaku.querybuilder.Where; import java.util.ArrayList; import java.util.List; -public class SQLSelectQuery implements Selectable { +public class SQLSelectQuery implements SQLQuery, Selectable { - private final List internalQueries = new ArrayList(); + private final List internalQueries = new ArrayList(); - private InternalQuery currentInternalQuery; - private OrderBy orderBy; - private Integer limit = null, offset = null; + private InternalQuery currentInternalQuery; + private OrderBy orderBy; + private Integer limit = null, offset = null; - SQLSelectQuery() { - initCurrentQuery(); - } + SQLSelectQuery() { + initCurrentQuery(); + } - @Override - public String getSQL() { - final StringBuilder sb = new StringBuilder(); - final int size = internalQueries.size(); - for (int i = 0; i < size; i++) { - if (i != 0) { - sb.append("UNION "); - } - final InternalQuery query = internalQueries.get(i); - sb.append(query.getSQL()); + @Override + public String getSQL() { + final StringBuilder sb = new StringBuilder(); + final int size = internalQueries.size(); + for (int i = 0; i < size; i++) { + if (i != 0) { + sb.append("UNION "); + } + final InternalQuery query = internalQueries.get(i); + sb.append(query.getSQL()); - } - if (orderBy != null) { - sb.append(String.format("ORDER BY %s ", orderBy.getSQL())); - } - if (limit != null) { - sb.append(String.format("LIMIT %s ", limit)); - if (offset != null) { - sb.append(String.format("OFFSET %s ", offset)); - } - } - return sb.toString(); - } + } + if (orderBy != null) { + sb.append(String.format("ORDER BY %s ", orderBy.getSQL())); + } + if (limit != null) { + sb.append(String.format("LIMIT %s ", limit)); + if (offset != null) { + sb.append(String.format("OFFSET %s ", offset)); + } + } + return sb.toString(); + } - private void initCurrentQuery() { - currentInternalQuery = new InternalQuery(); - internalQueries.add(currentInternalQuery); - } + private void initCurrentQuery() { + currentInternalQuery = new InternalQuery(); + internalQueries.add(currentInternalQuery); + } - void setDistinct(final boolean distinct) { - currentInternalQuery.setDistinct(distinct); - } + void setDistinct(final boolean distinct) { + currentInternalQuery.setDistinct(distinct); + } - void setFrom(final Selectable from) { - currentInternalQuery.setFrom(from); - } + void setFrom(final Selectable from) { + currentInternalQuery.setFrom(from); + } - void setGroupBy(final Selectable groupBy) { - currentInternalQuery.setGroupBy(groupBy); - } + void setGroupBy(final Selectable groupBy) { + currentInternalQuery.setGroupBy(groupBy); + } - void setHaving(final Where having) { - currentInternalQuery.setHaving(having); - } + void setHaving(final Expression having) { + currentInternalQuery.setHaving(having); + } - void setLimit(final int limit) { - this.limit = limit; - } + void setLimit(final int limit) { + this.limit = limit; + } - void setOffset(final int offset) { - this.offset = offset; - } + void setOffset(final int offset) { + this.offset = offset; + } - void setOrderBy(final OrderBy orderBy) { - this.orderBy = orderBy; - } + void setOrderBy(final OrderBy orderBy) { + this.orderBy = orderBy; + } - void setSelect(final Selectable select) { - currentInternalQuery.setSelect(select); - } + void setSelect(final Selectable select) { + currentInternalQuery.setSelect(select); + } - void setWhere(final Where where) { - currentInternalQuery.setWhere(where); - } + void setWhere(final Expression where) { + currentInternalQuery.setWhere(where); + } - void union() { - initCurrentQuery(); - } + void union() { + initCurrentQuery(); + } - public static final class Builder implements IBuilder { - private boolean buildCalled; - private final SQLSelectQuery query = new SQLSelectQuery(); + public static final class Builder implements IBuilder { + private final SQLSelectQuery query = new SQLSelectQuery(); + private boolean buildCalled; - @Override - public SQLSelectQuery build() { - buildCalled = true; - return query; - } + @Override + public SQLSelectQuery build() { + buildCalled = true; + return query; + } - @Override - public String buildSQL() { - return build().getSQL(); - } + @Override + public String buildSQL() { + return build().getSQL(); + } - public Builder from(final Selectable from) { - checkNotBuilt(); - query.setFrom(from); - return this; - } + public Builder from(final Selectable from) { + checkNotBuilt(); + query.setFrom(from); + return this; + } - public Builder groupBy(final Selectable groupBy) { - checkNotBuilt(); - query.setGroupBy(groupBy); - return this; - } + public Builder groupBy(final Selectable groupBy) { + checkNotBuilt(); + query.setGroupBy(groupBy); + return this; + } - public Builder having(final Where having) { - checkNotBuilt(); - query.setHaving(having); - return this; - } + public Builder having(final Expression having) { + checkNotBuilt(); + query.setHaving(having); + return this; + } - public Builder limit(final int limit) { - checkNotBuilt(); - query.setLimit(limit); - return this; - } + public Builder limit(final int limit) { + checkNotBuilt(); + query.setLimit(limit); + return this; + } - public Builder offset(final int offset) { - query.setOffset(offset); - return this; - } + public Builder offset(final int offset) { + query.setOffset(offset); + return this; + } - public Builder orderBy(final OrderBy orderBy) { - checkNotBuilt(); - query.setOrderBy(orderBy); - return this; - } + public Builder orderBy(final OrderBy orderBy) { + checkNotBuilt(); + query.setOrderBy(orderBy); + return this; + } - public Builder select(final boolean distinct, final Selectable select) { - checkNotBuilt(); - query.setSelect(select); - query.setDistinct(distinct); - return this; - } + public Builder select(final boolean distinct, final Selectable select) { + checkNotBuilt(); + query.setSelect(select); + query.setDistinct(distinct); + return this; + } - public Builder select(final Selectable select) { - checkNotBuilt(); - select(false, select); - return this; - } + public Builder select(final Selectable select) { + checkNotBuilt(); + select(false, select); + return this; + } - public Builder union() { - checkNotBuilt(); - query.union(); - return this; - } + public Builder union() { + checkNotBuilt(); + query.union(); + return this; + } - public Builder where(final Where where) { - checkNotBuilt(); - query.setWhere(where); - return this; - } + public Builder where(final Expression where) { + checkNotBuilt(); + query.setWhere(where); + return this; + } - private void checkNotBuilt() { - if (buildCalled) throw new IllegalStateException(); - } + private void checkNotBuilt() { + if (buildCalled) throw new IllegalStateException(); + } - } + } - private static class InternalQuery implements SQLLang { + private static class InternalQuery implements SQLLang { - private boolean distinct; - private Selectable select, from, groupBy; - private Where where, having; + private boolean distinct; + private Selectable select, from, groupBy; + private Expression where, having; - @Override - public String getSQL() { - if (select == null) throw new SQLQueryException("selectable is null"); - final StringBuilder sb = new StringBuilder("SELECT "); - if (distinct) { - sb.append("DISTINCT "); - } - sb.append(String.format("%s ", select.getSQL())); - if (!(select instanceof SQLSelectQuery) && from == null) - throw new SQLQueryException("FROM not specified"); - else if (from != null) { - if (from instanceof SQLSelectQuery) { - sb.append(String.format("FROM (%s) ", from.getSQL())); - } else { - sb.append(String.format("FROM %s ", from.getSQL())); - } - } - if (where != null) { - sb.append(String.format("WHERE %s ", where.getSQL())); - } - if (groupBy != null) { - sb.append(String.format("GROUP BY %s ", groupBy.getSQL())); - if (having != null) { - sb.append(String.format("HAVING %s ", having.getSQL())); - } - } - return sb.toString(); - } + @Override + public String getSQL() { + if (select == null) throw new SQLQueryException("selectable is null"); + final StringBuilder sb = new StringBuilder("SELECT "); + if (distinct) { + sb.append("DISTINCT "); + } + sb.append(String.format("%s ", select.getSQL())); + if (!(select instanceof SQLSelectQuery) && from == null) + throw new SQLQueryException("FROM not specified"); + else if (from != null) { + if (from instanceof SQLSelectQuery) { + sb.append(String.format("FROM (%s) ", from.getSQL())); + } else { + sb.append(String.format("FROM %s ", from.getSQL())); + } + } + if (where != null) { + sb.append(String.format("WHERE %s ", where.getSQL())); + } + if (groupBy != null) { + sb.append(String.format("GROUP BY %s ", groupBy.getSQL())); + if (having != null) { + sb.append(String.format("HAVING %s ", having.getSQL())); + } + } + return sb.toString(); + } - void setDistinct(final boolean distinct) { - this.distinct = distinct; - } + void setDistinct(final boolean distinct) { + this.distinct = distinct; + } - void setFrom(final Selectable from) { - this.from = from; - } + void setFrom(final Selectable from) { + this.from = from; + } - void setGroupBy(final Selectable groupBy) { - this.groupBy = groupBy; - } + void setGroupBy(final Selectable groupBy) { + this.groupBy = groupBy; + } - void setHaving(final Where having) { - this.having = having; - } + void setHaving(final Expression having) { + this.having = having; + } - void setSelect(final Selectable select) { - this.select = select; - } + void setSelect(final Selectable select) { + this.select = select; + } - void setWhere(final Where where) { - this.where = where; - } - } + void setWhere(final Expression where) { + this.where = where; + } + } } diff --git a/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLUpdateQuery.java b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLUpdateQuery.java new file mode 100644 index 000000000..f93177ebe --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/querybuilder/query/SQLUpdateQuery.java @@ -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 { + + 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(); + } + + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/TwidereConstants.java b/twidere/src/main/java/org/mariotaku/twidere/TwidereConstants.java index 604fd9845..b33c4b71b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/TwidereConstants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/TwidereConstants.java @@ -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 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_DRAFTS = 4; public static final int NOTIFICATION_ID_DATA_PROFILING = 5; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/FiltersActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/FiltersActivity.java index 2397e4055..358718a1c 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/FiltersActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/FiltersActivity.java @@ -33,6 +33,7 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -45,7 +46,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.AutoCompleteTextView; -import org.mariotaku.querybuilder.Where; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.BaseSupportActivity; import org.mariotaku.twidere.activity.support.UserListSelectorActivity; @@ -83,25 +84,19 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, } @Override - 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); + public boolean onCreateOptionsMenu(final Menu menu) { + getMenuInflater().inflate(R.menu.menu_filters, menu); + return true; } @Override - public boolean onCreateOptionsMenu(final Menu menu) { - getMenuInflater().inflate(R.menu.menu_filters, menu); + public boolean onPrepareOptionsMenu(final Menu 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; } @@ -140,7 +135,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, } case R.id.enable_in_mentions: { 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(); break; } @@ -155,12 +150,29 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, } @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 - 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 @@ -170,18 +182,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, } @Override - public boolean onPrepareOptionsMenu(final Menu 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, 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) { + public void onPageScrollStateChanged(final int state) { } @@ -195,6 +196,11 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, } + @Override + public void onTabReselected(final Tab tab, final FragmentTransaction ft) { + + } + @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { switch (requestCode) { @@ -205,7 +211,7 @@ public class FiltersActivity extends BaseSupportActivity implements TabListener, final ParcelableUser user = data.getParcelableExtra(EXTRA_USER); final ContentValues values = ContentValuesCreator.makeFilteredUserContentValues(user); 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); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java index 2218210a1..5b1a4f7f6 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/SettingsActivity.java @@ -41,6 +41,7 @@ import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewParent; import android.widget.BaseAdapter; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; 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_SPACE = 2; - private final Context mContext; private final Resources mResources; private final int mActionIconColor; private final ArrayList
mHeaders; @@ -244,7 +244,6 @@ public class SettingsActivity extends BasePreferenceActivity { private boolean mFirstItemIsCategory; public HeaderAdapter(final Context context) { - mContext = context; mInflater = LayoutInflater.from(context); mHeaders = new ArrayList<>(); mResources = context.getResources(); @@ -385,6 +384,13 @@ public class SettingsActivity extends BasePreferenceActivity { holder.icon.setImageDrawable(null); } 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) { @@ -424,12 +430,14 @@ public class SettingsActivity extends BasePreferenceActivity { private static class HeaderViewHolder extends ViewHolder { private final TextView title, summary; private final ImageView icon; + private final LinearLayout content; HeaderViewHolder(final View view) { super(view); title = (TextView) findViewById(android.R.id.title); summary = (TextView) findViewById(android.R.id.summary); icon = (ImageView) findViewById(android.R.id.icon); + content = (LinearLayout) findViewById(android.R.id.content); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java index 4f294c019..9590ebba2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/ComposeActivity.java @@ -83,8 +83,8 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.BaseArrayAdapter; import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment; -import org.mariotaku.twidere.model.Account; import org.mariotaku.twidere.model.DraftItem; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableMediaUpdate; @@ -186,7 +186,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa private boolean mIsPossiblySensitive, mShouldSaveAccounts; - private long[] mAccountIds, mSendAccountIds; + private long[] mSendAccountIds; private Uri mTempPhotoUri; private boolean mImageUploaderUsed, mStatusShortenerUsed; @@ -537,7 +537,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa public void saveToDrafts() { final String text = mEditText != null ? ParseUtils.parseString(mEditText.getText()) : null; final ParcelableStatusUpdate.Builder builder = new ParcelableStatusUpdate.Builder(); - builder.accounts(Account.getAccounts(this, mSendAccountIds)); + builder.accounts(ParcelableAccount.getAccounts(this, mSendAccountIds)); builder.text(text); builder.inReplyToStatusId(mInReplyToStatusId); builder.location(mRecentLocation); @@ -561,8 +561,8 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa setContentView(R.layout.activity_compose); setProgressBarIndeterminateVisibility(false); setFinishOnTouchOutside(false); - mAccountIds = getAccountIds(this); - if (mAccountIds.length <= 0) { + final long[] defaultAccountIds = getAccountIds(this); + if (defaultAccountIds.length <= 0) { final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN); intent.setClass(this, SignInActivity.class); startActivity(intent); @@ -574,7 +574,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa mEditText.setOnEditorActionListener(mPreferences.getBoolean(KEY_QUICK_SEND, false) ? this : null); mEditText.addTextChangedListener(this); 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.setInputMethodMode(IListPopupWindow.INPUT_METHOD_NOT_NEEDED); 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) { final long[] idsInPrefs = ArrayUtils.parseLongArray( mPreferences.getString(KEY_COMPOSE_ACCOUNTS, null), ','); - final long[] intersection = ArrayUtils.intersection(idsInPrefs, mAccountIds); - mSendAccountIds = intersection.length > 0 ? intersection : mAccountIds; + final long[] intersection = ArrayUtils.intersection(idsInPrefs, defaultAccountIds); + mSendAccountIds = intersection.length > 0 ? intersection : defaultAccountIds; } mOriginalText = ParseUtils.parseString(mEditText.getText()); } @@ -732,7 +732,18 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa private boolean handleDefaultIntent(final Intent intent) { if (intent == null) return false; 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 CharSequence extraSubject = intent.getCharSequenceExtra(Intent.EXTRA_SUBJECT); 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 { + private static class AccountSelectorAdapter extends BaseArrayAdapter { public AccountSelectorAdapter(final Context context) { super(context, android.R.layout.simple_list_item_multiple_choice); @@ -1284,7 +1295,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa @Override public View getView(int position, View convertView, ViewGroup 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); text1.setText(Utils.getAccountDisplayName(getContext(), account.account_id, isDisplayNameFirst())); return view; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/CustomTabEditorActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/CustomTabEditorActivity.java index be35d00fb..59deedd67 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/CustomTabEditorActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/CustomTabEditorActivity.java @@ -48,7 +48,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; import org.mariotaku.twidere.adapter.ArrayAdapter; import org.mariotaku.twidere.app.TwidereApplication; 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.ExtraConfiguration; 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); final boolean accountIdRequired = conf.getAccountRequirement() == CustomTabConfiguration.ACCOUNT_REQUIRED; if (!accountIdRequired) { - mAccountsAdapter.add(Account.dummyInstance()); + mAccountsAdapter.add(ParcelableAccount.dummyInstance()); } 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()) { case CustomTabConfiguration.FIELD_TYPE_USER: { mSecondaryFieldLabel.setText(R.string.user); diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/DraftsActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/DraftsActivity.java index 74f33d20a..1ea5eb8d9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/DraftsActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/DraftsActivity.java @@ -50,8 +50,8 @@ import android.widget.ListView; import org.mariotaku.menucomponent.widget.PopupMenu; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.DraftsAdapter; import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment; @@ -106,7 +106,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac } } 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())); mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null); } @@ -237,7 +237,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac final Bundle bundle = new Bundle(); bundle.putParcelable(EXTRA_DRAFT, draft); 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); } @@ -307,7 +307,7 @@ public class DraftsActivity extends BaseSupportActivity implements LoaderCallbac @Override protected Integer doInBackground(final Void... params) { 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 Cursor c = resolver.query(Drafts.CONTENT_URI, projection, where.getSQL(), null, null); final int idxMedia = c.getColumnIndex(Drafts.MEDIA); diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java index c19a31ab7..58e7588c3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java @@ -77,7 +77,7 @@ import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment; import org.mariotaku.twidere.fragment.support.DirectMessagesFragment; import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment; 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.provider.TweetStore.Accounts; import org.mariotaku.twidere.task.AsyncTask; @@ -146,7 +146,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener private final ArrayList mCustomTabs = new ArrayList(); private final SparseArray mAttachedFragments = new SparseArray(); - private Account mSelectedAccountToSearch; + private ParcelableAccount mSelectedAccountToSearch; 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; onSearchRequested(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java index 0b397dab0..e8f7dbb5b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/LinkHandlerActivity.java @@ -210,8 +210,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL break; } case LINK_ID_STATUS: { -// transitionRes = R.transition.transition_status; - transitionRes = 0; + transitionRes = R.transition.transition_status; break; } default: { @@ -221,7 +220,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL } if (transitionRes != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !ThemeUtils.isTransparentBackground(this)) { - Utils.setSharedElementTransition(this, window, R.transition.transition_status); + Utils.setSharedElementTransition(this, window, transitionRes); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java index f1ff8a54c..1d33afeb8 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java @@ -14,7 +14,6 @@ import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IStatusesAdapter; 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.UserFragment; import org.mariotaku.twidere.model.ParcelableStatus; @@ -42,6 +41,8 @@ public abstract class AbsStatusesAdapter extends Adapter implemen private final int mCardLayoutResource; private boolean mLoadMoreIndicatorEnabled; + private EventListener mEventListener; + public AbsStatusesAdapter(Context context, boolean compact) { mContext = context; mInflater = LayoutInflater.from(context); @@ -59,7 +60,7 @@ public abstract class AbsStatusesAdapter extends Adapter implemen switch (viewType) { case ITEM_VIEW_TYPE_STATUS: { final View view = mInflater.inflate(mCardLayoutResource, parent, false); - return new StatusViewHolder<>(this, view); + return new StatusViewHolder(this, view); } case ITEM_VIEW_TYPE_GAP: { final View view = mInflater.inflate(R.layout.card_item_gap, parent, false); @@ -126,16 +127,10 @@ public abstract class AbsStatusesAdapter extends Adapter implemen } @Override - public void onStatusClick(StatusViewHolder holder, int position) { - final Context context = getContext(); -// 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); -// } + public final void onStatusClick(StatusViewHolder holder, int position) { + if (mEventListener != null) { + mEventListener.onStatusClick(holder, position); + } } @Override @@ -153,18 +148,42 @@ public abstract class AbsStatusesAdapter extends Adapter implemen } @Override - public void onItemMenuClick(StatusViewHolder holder, int position) { - final Context context = getContext(); - if (!(context instanceof FragmentActivity)) return; - final Bundle args = new Bundle(); - args.putParcelable(EXTRA_STATUS, getStatus(position)); - final StatusMenuDialogFragment f = new StatusMenuDialogFragment(); - f.setArguments(args); - f.show(((FragmentActivity) context).getSupportFragmentManager(), "status_menu"); + public void onItemActionClick(ViewHolder holder, int id, int position) { + if (mEventListener != null) { + mEventListener.onStatusActionClick((StatusViewHolder) holder, id, position); + } + } + + @Override + public void onItemMenuClick(ViewHolder holder, int position) { + if (mEventListener != null) { + mEventListener.onStatusMenuClick((StatusViewHolder) holder, position); + } } public abstract void setData(D data); 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); + } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java index 8608312e1..c2f343ad7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsAdapter.java @@ -32,8 +32,8 @@ import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IBaseAdapter; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.Indices; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.Indices; import org.mariotaku.twidere.provider.TweetStore.Accounts; import org.mariotaku.twidere.util.ImageLoaderWrapper; 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); } - public Account getAccount(int position) { + public ParcelableAccount getAccount(int position) { final Cursor c = getCursor(); if (c == null || c.isClosed() || !c.moveToPosition(position)) return null; - return new Account(c, mIndices); + return new ParcelableAccount(c, mIndices); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsSpinnerAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsSpinnerAdapter.java index 8985b6ecb..d60f1b197 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsSpinnerAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AccountsSpinnerAdapter.java @@ -20,7 +20,6 @@ package org.mariotaku.twidere.adapter; import android.content.Context; -import android.graphics.PorterDuff.Mode; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -29,13 +28,12 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.app.TwidereApplication; 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.ThemeUtils; import java.util.Collection; -public class AccountsSpinnerAdapter extends ArrayAdapter { +public class AccountsSpinnerAdapter extends ArrayAdapter { private final ImageLoaderWrapper mImageLoader; private final boolean mDisplayProfileImage; @@ -48,7 +46,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter { Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true); } - public AccountsSpinnerAdapter(final Context context, final Collection accounts) { + public AccountsSpinnerAdapter(final Context context, final Collection accounts) { this(context); addAll(accounts); } @@ -67,7 +65,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter { 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 text2 = (TextView) view.findViewById(android.R.id.text2); final ImageView icon = (ImageView) view.findViewById(android.R.id.icon); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesAdapter.java index 044c0a301..7ac0c84c2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesAdapter.java @@ -73,11 +73,6 @@ public class CursorStatusesAdapter extends AbsStatusesAdapter { notifyDataSetChanged(); } - @Override - public void onGapClick(StatusViewHolder holder, int position) { - - } - @Override public Cursor getData() { return mCursor; diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesListAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesListAdapter.java index ef0da562e..0afbd7253 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesListAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/CursorStatusesListAdapter.java @@ -25,6 +25,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.support.v4.util.Pair; +import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -121,7 +122,12 @@ public class CursorStatusesListAdapter extends BaseCursorAdapter implements ISta } @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 - public void onGapClick(StatusViewHolder holder, int position) { + public void onGapClick(ViewHolder holder, int position) { } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/DirectMessageConversationEntriesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/DirectMessageConversationEntriesAdapter.java index c29146791..340a0e3b5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/DirectMessageConversationEntriesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/DirectMessageConversationEntriesAdapter.java @@ -33,7 +33,6 @@ import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries; import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.MultiSelectManager; -import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.view.holder.DirectMessageEntryViewHolder; 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 MultiSelectManager mMultiSelectManager; - private boolean mAnimationEnabled; - private int mMaxAnimationPosition; - public DirectMessageConversationEntriesAdapter(final Context context) { - this(context, Utils.isCompactCards(context)); - } - - public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards) { - super(context, getItemResource(compactCards), null, new String[0], new int[0], 0); + super(context, R.layout.list_item_message_entry, null, new String[0], new int[0], 0); final TwidereApplication app = TwidereApplication.getInstance(context); mMultiSelectManager = app.getMultiSelectManager(); mImageLoader = app.getImageLoaderWrapper(); @@ -96,8 +88,6 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i final String nick = getUserNickname(context, conversationId); holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString( 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.time.setTime(timestamp); holder.setIsOutgoing(isOutgoing); @@ -110,12 +100,6 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i } else { mImageLoader.cancelDisplayTask(holder.profile_image); } - if (position > mMaxAnimationPosition) { - if (mAnimationEnabled) { - view.startAnimation(holder.item_animation); - } - mMaxAnimationPosition = position; - } super.bindView(view, context, cursor); } @@ -175,20 +159,14 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i @Override public void setAnimationEnabled(final boolean anim) { - if (mAnimationEnabled == anim) return; - mAnimationEnabled = anim; } @Override public void setMaxAnimationPosition(final int position) { - mMaxAnimationPosition = position; } @Override 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; - } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableStatusesAdapter.java index ff1c5b711..e92caff26 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/ParcelableStatusesAdapter.java @@ -23,11 +23,6 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter { - void onItemMenuClick(VH holder, int position); +public interface ICardSupportedAdapter { + void onItemActionClick(ViewHolder holder, int id, int position); + + void onItemMenuClick(ViewHolder holder, int position); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IGapSupportedAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IGapSupportedAdapter.java index c07675892..461144545 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IGapSupportedAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IGapSupportedAdapter.java @@ -24,10 +24,10 @@ import android.support.v7.widget.RecyclerView.ViewHolder; /** * Created by mariotaku on 14/12/3. */ -public interface IGapSupportedAdapter { +public interface IGapSupportedAdapter { boolean isGapItem(int position); - void onGapClick(VH holder, int position); + void onGapClick(ViewHolder holder, int position); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java index 31bde7ad7..7b5499ad5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/iface/IStatusesAdapter.java @@ -10,8 +10,7 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder; /** * Created by mariotaku on 14/11/18. */ -public interface IStatusesAdapter extends IGapSupportedAdapter, - IItemMenuSupportedAdapter { +public interface IStatusesAdapter extends IGapSupportedAdapter, ICardSupportedAdapter { ImageLoaderWrapper getImageLoader(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index 84e4c8a9a..0b9504bd3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -85,7 +85,7 @@ public interface IntentConstants { 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_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_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"; diff --git a/twidere/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java b/twidere/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java index ee0077b17..8b1f355d8 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java +++ b/twidere/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java @@ -253,7 +253,7 @@ public interface SharedPreferenceConstants { @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_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"; @Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false) public static final String KEY_NICKNAME_ONLY = "nickname_only"; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/AccountNotificationSettingsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/AccountNotificationSettingsFragment.java index 04cf15552..87fff3f26 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/AccountNotificationSettingsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/AccountNotificationSettingsFragment.java @@ -23,7 +23,7 @@ import android.os.Bundle; import android.preference.Preference; import org.mariotaku.twidere.R; -import org.mariotaku.twidere.model.Account; +import org.mariotaku.twidere.model.ParcelableAccount; public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFragment { @@ -31,7 +31,7 @@ public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFr public void onActivityCreated(final Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); final Preference preference = findPreference(KEY_NOTIFICATION_LIGHT_COLOR); - final Account account = getAccount(); + final ParcelableAccount account = getAccount(); if (preference != null && account != null) { preference.setDefaultValue(account.color); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java index 1a5cc76fe..8b5ca25e0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseAccountPreferenceFragment.java @@ -39,7 +39,7 @@ import android.widget.Switch; import org.mariotaku.twidere.Constants; 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, OnCheckedChangeListener, OnSharedPreferenceChangeListener { @@ -49,7 +49,7 @@ public abstract class BaseAccountPreferenceFragment extends PreferenceFragment i super.onActivityCreated(savedInstanceState); setHasOptionsMenu(true); 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 + (account != null ? account.account_id : "unknown"); pm.setSharedPreferencesName(preferenceName); @@ -93,7 +93,7 @@ public abstract class BaseAccountPreferenceFragment extends PreferenceFragment i } } - protected Account getAccount() { + protected ParcelableAccount getAccount() { final Bundle args = getArguments(); if (args == null) return null; return args.getParcelable(EXTRA_ACCOUNT); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java index 9c2db588e..43169491b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/BaseFiltersFragment.java @@ -45,8 +45,8 @@ import android.widget.SimpleCursorAdapter; import android.widget.TextView; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.R; import org.mariotaku.twidere.fragment.support.BaseSupportListFragment; 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) { switch (item.getItemId()) { 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); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/CustomTabsFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/CustomTabsFragment.java index e5a4dbb42..03ff1398a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/CustomTabsFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/CustomTabsFragment.java @@ -52,8 +52,8 @@ import com.mobeta.android.dslv.SimpleDragSortCursorAdapter; import org.mariotaku.menucomponent.widget.PopupMenu; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.CustomTabEditorActivity; 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) { switch (item.getItemId()) { 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); break; } @@ -150,7 +150,7 @@ public class CustomTabsFragment extends BaseListFragment implements LoaderCallba values.put(Tabs.NAME, data.getStringExtra(EXTRA_NAME)); values.put(Tabs.ICON, data.getStringExtra(EXTRA_ICON)); 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); } break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java index 504103922..5c920e4a2 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java @@ -1,11 +1,13 @@ 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.graphics.Rect; import android.os.Bundle; import android.support.annotation.Nullable; -import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; import android.support.v4.widget.SwipeRefreshLayout; @@ -19,27 +21,77 @@ import android.view.ViewGroup; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.AbsStatusesAdapter; +import org.mariotaku.twidere.adapter.AbsStatusesAdapter.EventListener; 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.ThemeUtils; import org.mariotaku.twidere.util.Utils; 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. */ -public abstract class AbsStatusesFragment extends BaseSupportFragment - implements LoaderCallbacks, OnRefreshListener, DrawerCallback { +public abstract class AbsStatusesFragment extends BaseSupportFragment implements LoaderCallbacks, + 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 SharedPreferences mPreferences; + private View mProgressContainer; + private SwipeRefreshLayout mSwipeRefreshLayout; + private RecyclerView mRecyclerView; + private AbsStatusesAdapter 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 public void fling(float 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 public void scrollBy(float dy) { @@ -51,51 +103,34 @@ public abstract class AbsStatusesFragment extends BaseSupportFragment 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 public void topChanged(int offset) { mDrawerCallback.topChanged(offset); } - private View mProgressContainer; - private SwipeRefreshLayout mSwipeRefreshLayout; - private RecyclerView mRecyclerView; + public AbsStatusesAdapter getAdapter() { + return mAdapter; + } - private AbsStatusesAdapter 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() { - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } + public boolean isRefreshing() { + return mSwipeRefreshLayout.isRefreshing(); + } - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); - final LoaderManager lm = getLoaderManager(); - if (lm.hasRunningLoaders()) return; - if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) { - final long[] maxIds = new long[]{mAdapter.getStatus(mAdapter.getStatusCount() - 1).id}; - getStatuses(null, maxIds, null); - } - } - }; + public void setRefreshing(boolean refreshing) { + mSwipeRefreshLayout.setRefreshing(refreshing); + } + + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_recycler_view, container, false); + } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { @@ -116,17 +151,86 @@ public abstract class AbsStatusesFragment extends BaseSupportFragment } mRecyclerView.setAdapter(mAdapter); mRecyclerView.setOnScrollListener(mOnScrollListener); + mAdapter.setEventListener(this); getLoaderManager().initLoader(0, getArguments(), this); setListShown(false); } - protected abstract AbsStatusesAdapter onCreateAdapter(Context context, boolean compact); - - private void setListShown(boolean shown) { - mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE); - mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE); + @Override + public void onStart() { + super.onStart(); + final IntentFilter filter = new IntentFilter(); + onSetIntentFilter(filter); + registerReceiver(mStateReceiver, filter); } + @Override + public void onStop() { + unregisterReceiver(mStateReceiver); + super.onStop(); + } + + @Override + public void onLoadFinished(Loader loader, Data data) { + setRefreshing(false); + mAdapter.setData(data); + setListShown(true); + } + + @Override + public void onLoaderReset(Loader 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 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { @@ -144,44 +248,36 @@ public abstract class AbsStatusesFragment extends BaseSupportFragment } @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_recycler_view, container, false); + public boolean scrollToStart() { + 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() { return mAdapter.getData(); } - public void setRefreshing(boolean refreshing) { - mSwipeRefreshLayout.setRefreshing(refreshing); - } - - @Override - public void onLoadFinished(Loader loader, Data data) { - setRefreshing(false); + protected void setAdapterData(Data data) { mAdapter.setData(data); - setListShown(true); } - @Override - public void onLoaderReset(Loader loader) { + protected abstract AbsStatusesAdapter onCreateAdapter(Context context, boolean compact); + + 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); - } - - } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java index c49552e48..130715dd1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsDashboardFragment.java @@ -28,6 +28,7 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Bitmap; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.os.Bundle; @@ -54,20 +55,24 @@ import android.widget.Switch; import android.widget.TextView; 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.activity.FiltersActivity; import org.mariotaku.twidere.activity.SettingsActivity; import org.mariotaku.twidere.activity.iface.IThemedActivity; 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.HomeActivity; import org.mariotaku.twidere.activity.support.UserProfileEditorActivity; import org.mariotaku.twidere.adapter.ArrayAdapter; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.Indices; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.Indices; import org.mariotaku.twidere.provider.TweetStore.Accounts; +import org.mariotaku.twidere.util.CompareUtils; import org.mariotaku.twidere.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.Utils; @@ -76,13 +81,11 @@ import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver; import java.util.ArrayList; 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.openUserProfile; -import static org.mariotaku.twidere.util.Utils.openUserTimeline; public class AccountsDashboardFragment extends BaseSupportListFragment implements LoaderCallbacks, - OnSharedPreferenceChangeListener, OnCheckedChangeListener { + OnSharedPreferenceChangeListener, OnCheckedChangeListener, ImageLoadingListener, OnClickListener { private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver( this, 0, this); @@ -106,48 +109,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement private Context mThemedContext; 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 public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { switch (requestCode) { @@ -163,14 +124,57 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement 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(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE)); + openUserProfile(activity, account.account_id, account.account_id, + account.screen_name, activityOption); + break; + } + } + } + @Override public Loader onCreateLoader(final int id, final Bundle args) { return new CursorLoader(getActivity(), Accounts.CONTENT_URI, Accounts.COLUMNS, null, null, Accounts.SORT_POSITION); } @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); + public void onLoadFinished(final Loader loader, final Cursor data) { + 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 loader) { + mAccountsAdapter.changeCursor(null); } @Override @@ -178,18 +182,10 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement final ListAdapter adapter = mAdapter.getAdapter(position); final Object item = mAdapter.getItem(position); if (adapter instanceof AccountOptionsAdapter) { - final Account account = mAccountsAdapter.getSelectedAccount(); + final ParcelableAccount account = mAccountsAdapter.getSelectedAccount(); if (account == null || !(item instanceof OptionItem)) return; final OptionItem option = (OptionItem) item; switch (option.id) { - case MENU_VIEW_PROFILE: { - final FragmentActivity activity = getActivity(); - final Bundle activityOption = Utils.makeSceneTransitionOption(activity, - new Pair(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE)); - openUserProfile(activity, account.account_id, account.account_id, - account.screen_name, activityOption); - break; - } case MENU_SEARCH: { final FragmentActivity a = getActivity(); if (a instanceof HomeActivity) { @@ -200,8 +196,11 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement closeAccountsDrawer(); break; } - case MENU_STATUSES: { - openUserTimeline(getActivity(), account.account_id, account.account_id, account.screen_name); + case MENU_COMPOSE: { + 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; } case MENU_FAVORITES: { @@ -212,10 +211,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name); break; } - case MENU_LIST_MEMBERSHIPS: { - openUserListMemberships(getActivity(), account.account_id, account.account_id, account.screen_name); - break; - } case MENU_EDIT: { final Bundle bundle = new Bundle(); bundle.putLong(EXTRA_ACCOUNT_ID, account.account_id); @@ -259,25 +254,23 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement } @Override - public void onLoaderReset(final Loader loader) { - mAccountsAdapter.changeCursor(null); + public void onLoadingStarted(String imageUri, View view) { + } @Override - public void onLoadFinished(final Loader loader, final Cursor data) { - 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(); + public void onLoadingFailed(String imageUri, View view, FailReason failReason) { + } @Override - public void onResume() { - super.onResume(); - updateDefaultAccountState(); + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + view.setTag(imageUri); + } + + @Override + public void onLoadingCancelled(String imageUri, View view) { + } @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 public void onStart() { super.onStart(); @@ -316,8 +362,21 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement 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() { - final Account account = mAccountsAdapter.getSelectedAccount(); + final ParcelableAccount account = mAccountsAdapter.getSelectedAccount(); if (account == null) { return; } @@ -329,43 +388,23 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement final Resources res = getResources(); final int defWidth = res.getDisplayMetrics().widthPixels; 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 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 ArrayList sOptions = new ArrayList<>(); 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(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.lists, R.drawable.ic_action_list, MENU_LISTS)); } @@ -423,6 +462,36 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement 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 public AccountProfileImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 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); } - 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) { final Cursor c = mCursor; c.moveToPosition(position); 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 final int name, icon, id; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java index e6818b0cb..ff9b89140 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AccountsManagerFragment.java @@ -35,12 +35,12 @@ import android.widget.ListView; import com.mobeta.android.dslv.DragSortListView; 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.activity.support.ColorPickerDialogActivity; import org.mariotaku.twidere.activity.support.SignInActivity; 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.DirectMessages; import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Inbox; @@ -61,7 +61,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements private AccountsAdapter mAdapter; private SharedPreferences mPreferences; - private Account mSelectedAccount; + private ParcelableAccount mSelectedAccount; @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -178,7 +178,7 @@ public class AccountsManagerFragment extends BaseSupportListFragment implements public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (!(menuInfo instanceof AdapterContextMenuInfo)) return; final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - final Account account = mAdapter.getAccount(info.position); + final ParcelableAccount account = mAdapter.getAccount(info.position); menu.setHeaderTitle(account.name); final MenuInflater inflater = new MenuInflater(v.getContext()); 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 ContentValues values = new ContentValues(); 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); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshStaggeredGridFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshStaggeredGridFragment.java deleted file mode 100644 index ade095f4a..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BasePullToRefreshStaggeredGridFragment.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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 must have a ListView whose id is - * {@link android.R.id#list android.R.id.list} and can optionally have a - * sibling view id {@link android.R.id#empty android.R.id.empty} that is to - * be shown when the list is empty. - *

- * If you are overriding this method with your own custom content, consider - * including the standard layout {@link android.R.layout#list_content} in - * your layout file, so that you continue to retain all of the standard - * behavior of ListFragment. In particular, this is currently the only way - * to have the built-in indeterminant progress state be shown. - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { - final Context context = getActivity(); - - final FrameLayout root = new FrameLayout(context); - - // ------------------------------------------------------------------ - - final LinearLayout pframe = new LinearLayout(context); - pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID); - pframe.setOrientation(LinearLayout.VERTICAL); - pframe.setVisibility(View.GONE); - pframe.setGravity(Gravity.CENTER); - - final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge); - pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - // ------------------------------------------------------------------ - - final FrameLayout lframe = new FrameLayout(context); - lframe.setId(INTERNAL_LIST_CONTAINER_ID); - - final TextView tv = new TextView(getActivity()); - tv.setId(INTERNAL_EMPTY_ID); - tv.setGravity(Gravity.CENTER); - lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - final 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() { - - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesListFragment.java index 24f846995..a893cbe41 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesListFragment.java @@ -40,8 +40,8 @@ import android.widget.ListView; 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.Account; -import org.mariotaku.twidere.model.Account.AccountWithCredentials; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.task.AsyncTask; import org.mariotaku.twidere.util.AsyncTaskManager; @@ -345,9 +345,9 @@ abstract class BaseStatusesListFragment extends BasePullToRefreshListFragm break; } case MENU_TRANSLATE: { - final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(), + final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(), status.account_id); - if (AccountWithCredentials.isOfficialCredentials(getActivity(), account)) { + if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) { StatusTranslateDialogFragment.show(getFragmentManager(), status); } else { diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesStaggeredGridFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesStaggeredGridFragment.java deleted file mode 100644 index 5e9fba080..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseStatusesStaggeredGridFragment.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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 extends BasePullToRefreshStaggeredGridFragment implements - LoaderCallbacks, OnItemLongClickListener, OnMenuItemClickListener, - MultiSelectManager.Callback, MenuButtonClickListener { - - private AsyncTaskManager mAsyncTaskManager; - private SharedPreferences mPreferences; - - private StaggeredGridView mListView; - private IStatusesListAdapter 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> mUnreadCountsToRemove = Collections - .synchronizedMap(new HashMap>()); - private final List mReadPositions = new NoDuplicatesCopyOnWriteArrayList(); - - private RemoveUnreadCountsTask mRemoveUnreadCountsTask; - - public AsyncTaskManager getAsyncTaskManager() { - return mAsyncTaskManager; - } - - public final Data getData() { - return mData; - } - - @Override - public IStatusesListAdapter 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> 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 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 loader) { - mAdapter.setData(mData = null); - } - - @Override - public final void onLoadFinished(final Loader 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 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 counts = mUnreadCountsToRemove.get(account_id); - counts.add(id); - } else { - final Set counts = new HashSet(); - 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(mReadPositions, this); - mRemoveUnreadCountsTask.execute(); - } - - static class RemoveUnreadCountsTask extends AsyncTask { - private final List read_positions; - private final IStatusesListAdapter adapter; - private final BaseStatusesStaggeredGridFragment fragment; - - RemoveUnreadCountsTask(final List read_positions, final BaseStatusesStaggeredGridFragment 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()); - } - } - - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java index 7d39013fd..e5f05fb2b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportFragment.java @@ -114,7 +114,8 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons @Override public int getTabPosition() { - return 0; + final Bundle args = getArguments(); + return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1; } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportStaggeredGridFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportStaggeredGridFragment.java deleted file mode 100644 index 31bdaebeb..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/BaseSupportStaggeredGridFragment.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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() { - - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesFragment.java index bbfb7fad6..36bd80190 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesFragment.java @@ -20,18 +20,134 @@ package org.mariotaku.twidere.fragment.support; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +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 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.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. */ public abstract class CursorStatusesFragment extends AbsStatusesFragment { + + public abstract Uri getContentUri(); + + @Override + public Loader 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() { + + @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 protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) { return new CursorStatusesAdapter(context, compact); } + @Override + protected void onLoadMoreStatuses() { + new AsyncTask() { + + @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; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesListFragment.java deleted file mode 100644 index 3a033d600..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesListFragment.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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 { - - 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 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() { - - @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() { - - @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; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesStaggeredGridFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesStaggeredGridFragment.java deleted file mode 100644 index 990c887f3..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/CursorStatusesStaggeredGridFragment.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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 { - - 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 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() { - - @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() { - - @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; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java index c58a68713..0ed3fa44e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesConversationFragment.java @@ -64,7 +64,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter; import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter; import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener; 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.ParcelableUser; 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 ImageLoaderWrapper mImageLoader; private IColorLabelView mProfileImageContainer; @@ -174,7 +174,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra } mEditText.addTextChangedListener(this); - final List accounts = Account.getAccountsList(getActivity(), false); + final List accounts = ParcelableAccount.getAccountsList(getActivity(), false); mAccountSpinner.setAdapter(new AccountsSpinnerAdapter(getActivity(), accounts)); mAccountSpinner.setOnItemSelectedListener(this); @@ -331,7 +331,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra @Override 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) { mAccountId = account.account_id; mSender = account; @@ -487,7 +487,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra mAccountId = accountId; mRecipientId = recipientId; final Context context = getActivity(); - mSender = Account.getAccount(context, accountId); + mSender = ParcelableAccount.getAccount(context, accountId); mRecipient = Utils.getUserForConversation(context, accountId, recipientId); final LoaderManager lm = getLoaderManager(); final Bundle args = new Bundle(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java index 9c5e829cc..a9b099fca 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/DirectMessagesFragment.java @@ -37,8 +37,8 @@ import android.widget.AbsListView; import android.widget.ListView; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.DirectMessageConversationEntriesAdapter; import org.mariotaku.twidere.provider.TweetStore.Accounts; @@ -112,10 +112,7 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem mAdapter = new DirectMessageConversationEntriesAdapter(getActivity()); setListAdapter(mAdapter); mListView = getListView(); - if (!mPreferences.getBoolean(KEY_COMPACT_CARDS, false)) { - mListView.setDivider(null); - } - mListView.setSelector(android.R.color.transparent); + mListView.setDivider(null); getLoaderManager().initLoader(0, null, this); setListShown(false); } @@ -130,7 +127,7 @@ public class DirectMessagesFragment extends BasePullToRefreshListFragment implem if (!no_account_selected) { 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); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java index 7049822fd..5c05b7122 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineFragment.java @@ -19,33 +19,61 @@ package org.mariotaku.twidere.fragment.support; -import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; 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 org.mariotaku.twidere.adapter.CursorStatusesListAdapter; import org.mariotaku.twidere.provider.TweetStore.Statuses; +import org.mariotaku.twidere.util.AsyncTwitterWrapper; /** * Created by mariotaku on 14/12/3. */ public class HomeTimelineFragment extends CursorStatusesFragment { + @Override - public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) { - return 0; + public Uri getContentUri() { + return Statuses.CONTENT_URI; } @Override - public Loader onCreateLoader(int id, Bundle args) { - final Context context = getActivity(); - 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); + protected int getNotificationType() { + return NOTIFICATION_ID_HOME_TIMELINE; } + + @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()); + } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineListFragment.java deleted file mode 100644 index 363c586c7..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/HomeTimelineListFragment.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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()); - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsMenuDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsMenuDialogFragment.java index a37ab1180..a0895d954 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsMenuDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/IncomingFriendshipsMenuDialogFragment.java @@ -5,8 +5,8 @@ import android.view.Menu; import android.view.MenuInflater; import org.mariotaku.twidere.R; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.AccountWithCredentials; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials; import org.mariotaku.twidere.model.ParcelableUser; public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragment { @@ -14,8 +14,8 @@ public class IncomingFriendshipsMenuDialogFragment extends UserMenuDialogFragmen @Override protected void onPrepareItemMenu(final Menu menu, final ParcelableUser user) { final Context context = getThemedContext(); - final AccountWithCredentials account = Account.getAccountWithCredentials(context, user.account_id); - if (AccountWithCredentials.isOfficialCredentials(context, account)) { + final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(context, user.account_id); + if (ParcelableAccountWithCredentials.isOfficialCredentials(context, account)) { final MenuInflater inflater = new MenuInflater(context); inflater.inflate(R.menu.action_incoming_friendship, menu); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MentionsTimelineFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MentionsTimelineFragment.java index cdff2cf92..18b037f8b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MentionsTimelineFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/MentionsTimelineFragment.java @@ -1,18 +1,18 @@ /* - * Twidere - Twitter client for Android - * + * Twidere - Twitter client for Android + * * Copyright (C) 2012-2014 Mariotaku Lee - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -25,89 +25,57 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.Uri; -import android.os.Bundle; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.provider.TweetStore.Mentions; 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 - public void onReceive(final Context context, final Intent intent) { - if (getActivity() == null || !isAdded() || isDetached()) return; - final String action = intent.getAction(); - if (BROADCAST_MENTIONS_REFRESHED.equals(action)) { - setRefreshComplete(); - } else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) { - updateRefreshState(); - } - } - }; + @Override + protected int getNotificationType() { + return NOTIFICATION_ID_MENTIONS_TIMELINE; + } - @Override - public int getStatuses(final long[] account_ids, final long[] max_ids, final long[] since_ids) { - final AsyncTwitterWrapper twitter = getTwitterWrapper(); - if (twitter == null) return -1; - return twitter.getMentionsAsync(account_ids, max_ids, since_ids); - } + @Override + protected boolean isFilterEnabled() { + final SharedPreferences pref = getSharedPreferences(); + return pref != null && pref.getBoolean(KEY_FILTERS_IN_MENTIONS_TIMELINE, true); + } - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getListAdapter().setMentionsHightlightDisabled(true); - } + @Override + public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) { + final AsyncTwitterWrapper twitter = getTwitterWrapper(); + if (twitter == null) return -1; + return twitter.getMentionsTimelineAsync(accountIds, maxIds, sinceIds); + } - @Override - public void onStart() { - super.onStart(); - final IntentFilter filter = new IntentFilter(BROADCAST_MENTIONS_REFRESHED); - filter.addAction(BROADCAST_TASK_STATE_CHANGED); - registerReceiver(mStatusReceiver, filter); - } + @Override + protected void onReceivedBroadcast(Intent intent, String action) { + switch (action) { + case BROADCAST_TASK_STATE_CHANGED: { + updateRefreshState(); + break; + } + } + } - @Override - public void onStop() { - unregisterReceiver(mStatusReceiver); - super.onStop(); - } + @Override + protected void onSetIntentFilter(IntentFilter filter) { + filter.addAction(BROADCAST_TASK_STATE_CHANGED); + } - @Override - protected Uri getContentUri() { - return Mentions.CONTENT_URI; - } - - @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()); - } + private void updateRefreshState() { + final AsyncTwitterWrapper twitter = getTwitterWrapper(); + if (twitter == null) return; + setRefreshing(twitter.isMentionsTimelineRefreshing()); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesFragment.java index 912b89864..64f97a0cb 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesFragment.java @@ -20,11 +20,15 @@ package org.mariotaku.twidere.fragment.support; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter; +import org.mariotaku.twidere.adapter.iface.IStatusesAdapter; import org.mariotaku.twidere.model.ParcelableStatus; +import java.util.ArrayList; import java.util.List; /** @@ -33,8 +37,31 @@ import java.util.List; public abstract class ParcelableStatusesFragment extends AbsStatusesFragment> { @Override - protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) { - return new ParcelableStatusesAdapter(context, compact); + protected void onSetIntentFilter(IntentFilter filter) { + 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 data = getAdapterData(); + if (statusId <= 0 || data == null) return; + final ArrayList 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 @@ -50,4 +77,39 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment> adapter = getAdapter(); + final long[] maxIds = new long[]{adapter.getStatus(adapter.getStatusCount() - 1).id}; + getStatuses(null, maxIds, null); + } + + @Override + public boolean triggerRefresh() { + final IStatusesAdapter> 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; + } + } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesListFragment.java index be00e9690..954fbfd29 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/ParcelableStatusesListFragment.java @@ -58,7 +58,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra if (statusId > 0) { 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 boolean retweeted = intent.getBooleanExtra(EXTRA_RETWEETED, false); if (status_id > 0 && !retweeted) { @@ -158,7 +158,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra public void onStart() { super.onStart(); final IntentFilter filter = new IntentFilter(BROADCAST_STATUS_DESTROYED); - filter.addAction(BROADCAST_RETWEET_CHANGED); + filter.addAction(BROADCAST_STATUS_RETWEETED); registerReceiver(mStateReceiver, filter); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java index 2e213df77..ae9a56c5d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/SearchFragment.java @@ -54,6 +54,15 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll 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 public Fragment getCurrentVisibleFragment() { return mCurrentVisibleFragment; diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredGridFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredGridFragment.java deleted file mode 100644 index 26095fae7..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredGridFragment.java +++ /dev/null @@ -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 must have a ListView whose id is - * {@link android.R.id#list android.R.id.list} and can optionally have a - * sibling view id {@link android.R.id#empty android.R.id.empty} that is to - * be shown when the list is empty. - * - *

- * If you are overriding this method with your own custom content, consider - * including the standard layout {@link android.R.layout#list_content} in - * your layout file, so that you continue to retain all of the standard - * behavior of ListFragment. In particular, this is currently the only way - * to have the built-in indeterminant progress state be shown. - */ - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { - final Context context = getActivity(); - - final FrameLayout root = new FrameLayout(context); - - // ------------------------------------------------------------------ - - final LinearLayout pframe = new LinearLayout(context); - pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID); - pframe.setOrientation(LinearLayout.VERTICAL); - pframe.setVisibility(View.GONE); - pframe.setGravity(Gravity.CENTER); - - final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge); - pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - // ------------------------------------------------------------------ - - final FrameLayout lframe = new FrameLayout(context); - lframe.setId(INTERNAL_LIST_CONTAINER_ID); - - final TextView tv = new TextView(getActivity()); - tv.setId(INTERNAL_EMPTY_ID); - tv.setGravity(Gravity.CENTER); - lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - - final 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. - * - *

- * 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); - } - } -} \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredHomeTimelineFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredHomeTimelineFragment.java deleted file mode 100644 index 1ddbbea74..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StaggeredHomeTimelineFragment.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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(); - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java index dbab3f284..7eaf31e99 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java @@ -74,8 +74,8 @@ import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity; import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter; import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.AccountWithCredentials; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; @@ -203,7 +203,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On } break; } - case BROADCAST_RETWEET_CHANGED: { + case BROADCAST_STATUS_RETWEETED: { final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1); if (status_id > 0 && status_id == getStatusId()) { getStatus(true); @@ -561,9 +561,9 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On } case R.id.favorites_container: { // TODO - final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(), + final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(), 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 : status.id); } @@ -689,7 +689,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On final IntentFilter filter = new IntentFilter(); filter.addAction(BROADCAST_FRIENDSHIP_CHANGED); filter.addAction(BROADCAST_FAVORITE_CHANGED); - filter.addAction(BROADCAST_RETWEET_CHANGED); + filter.addAction(BROADCAST_STATUS_RETWEETED); registerReceiver(mStatusReceiver, filter); updateUserColor(); final int text_size = mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity())); @@ -814,9 +814,9 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On break; } case MENU_TRANSLATE: { - final AccountWithCredentials account = Account.getAccountWithCredentials(getActivity(), + final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(), status.account_id); - if (AccountWithCredentials.isOfficialCredentials(getActivity(), account)) { + if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) { StatusTranslateDialogFragment.show(getFragmentManager(), status); } else { diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFavoritesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFavoritesFragment.java index 73d660eba..356ba2b5b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFavoritesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFavoritesFragment.java @@ -36,7 +36,6 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment { @Override public Loader> onCreateLoader(int id, Bundle args) { setRefreshing(true); - final List data = getAdapterData(); final Context context = getActivity(); final long accountId = args.getLong(EXTRA_ACCOUNT_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 String screenName = args.getString(EXTRA_SCREEN_NAME); final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1); - return new UserFavoritesLoader(context, accountId, userId, screenName, maxId, sinceId, data, - null, tabPosition); + return new UserFavoritesLoader(context, accountId, userId, screenName, maxId, sinceId, + getAdapterData(), null, tabPosition); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java index 5bf013ea8..6f9d3237b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java @@ -80,7 +80,7 @@ import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; 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.activity.support.AccountSelectorActivity; import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity; @@ -332,7 +332,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener mFollowButton.setText(R.string.follow); } 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); // I bet you don't want to see blocked user in your auto // complete list. @@ -926,7 +926,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final boolean filtering = Utils.isFilteringUser(getActivity(), user.id); final ContentResolver cr = getContentResolver(); 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); showInfoMessage(getActivity(), R.string.message_user_unmuted, false); } 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 background = ThemeUtils.getActionBarBackground(activity, 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); } @@ -1161,8 +1162,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final View profileBannerContainer = mProfileBannerContainer; final int spaceHeight = space.getHeight(); final float factor = MathUtils.clamp(offset / (float) spaceHeight, 0, 1); - profileBannerView.setAlpha(1.0f - factor / 8f); - profileBannerContainer.setTranslationY(-offset); + profileBannerContainer.setTranslationY(Math.max(-offset, -spaceHeight)); profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / 2); if (mActionBarBackground != null && mTintedStatusContent != null) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java index a8f7838af..29b69ed4e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListFragment.java @@ -32,12 +32,14 @@ import android.graphics.Rect; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.AsyncTaskLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; +import android.support.v7.widget.CardView; import android.text.method.LinkMovementMethod; import android.util.Log; import android.view.LayoutInflater; @@ -59,6 +61,7 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.UserListSelectorActivity; import org.mariotaku.twidere.adapter.support.SupportTabsAdapter; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; +import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUserList; import org.mariotaku.twidere.model.SingleResponse; @@ -86,7 +89,7 @@ import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability; public class UserListFragment extends BaseSupportFragment implements OnClickListener, LoaderCallbacks>, DrawerCallback, - SystemWindowsInsetsCallback { + SystemWindowsInsetsCallback, SupportFragmentCallback { private ImageLoaderWrapper mProfileImageLoader; private AsyncTwitterWrapper mTwitterWrapper; @@ -100,6 +103,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList private HeaderDrawerLayout mHeaderDrawerLayout; private ViewPager mViewPager; private PagerSlidingTabStrip mPagerIndicator; + private CardView mCardView; private SupportTabsAdapter mPagerAdapter; @@ -125,6 +129,59 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList } }; 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) { if (userList == null || getActivity() == null) return; @@ -149,6 +206,31 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList 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) { final LoaderManager lm = getLoaderManager(); lm.destroyLoader(0); @@ -320,29 +402,6 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList 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 public void onClick(final View view) { switch (view.getId()) { @@ -415,6 +474,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList final View headerView = mHeaderDrawerLayout.getHeader(); final View contentView = mHeaderDrawerLayout.getContent(); + mCardView = (CardView) headerView.findViewById(R.id.card); mProfileContainer = (ColorLabelRelativeLayout) headerView.findViewById(R.id.profile); mListNameView = (TextView) headerView.findViewById(R.id.list_name); mCreatedByView = (TextView) headerView.findViewById(R.id.created_by); @@ -441,44 +501,27 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList content.setClipToPadding(false); } - @Override - public void fling(float velocity) { - - } - - @Override - public void scrollBy(float dy) { - - } - - @Override - public boolean shouldLayoutHeaderBottom() { - return false; - } - - @Override - public boolean canScroll(float dy) { - return false; - } - - @Override - 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; + 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(); } public static class EditUserListDialogFragment extends BaseSupportDialogFragment implements diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineFragment.java index 0d35dcd54..0c9a82860 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineFragment.java @@ -1,75 +1,51 @@ /* - * Twidere - Twitter client for Android - * + * Twidere - Twitter client for Android + * * Copyright (C) 2012-2014 Mariotaku Lee - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.mariotaku.twidere.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 UserListTimelineFragment extends ParcelableStatusesListFragment { +/** + * Created by mariotaku on 14/12/2. + */ +public class UserListTimelineFragment extends ParcelableStatusesFragment { - @Override - public Loader> 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> 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; - } + @Override + public Loader> onCreateLoader(int id, Bundle args) { + setRefreshing(true); + if (args == null) return null; + final int listId = args.getInt(EXTRA_LIST_ID, -1); + final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1); + final long maxId = args.getLong(EXTRA_MAX_ID, -1); + final long sinceId = args.getLong(EXTRA_SINCE_ID, -1); + final long userId = args.getLong(EXTRA_USER_ID, -1); + final String screenName = args.getString(EXTRA_SCREEN_NAME); + final String listName = args.getString(EXTRA_LIST_NAME); + final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1); + return new UserListTimelineLoader(getActivity(), accountId, listId, userId, screenName, + listName, maxId, sinceId, getAdapterData(), null, tabPosition); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineListFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineListFragment.java new file mode 100644 index 000000000..1ffde1236 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserListTimelineListFragment.java @@ -0,0 +1,75 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.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> 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> 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; + } + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java b/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java index fe818267e..daef766da 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/menu/AccountActionProvider.java @@ -9,19 +9,19 @@ import android.view.SubMenu; import android.view.View; 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 static final int MENU_GROUP = 201; - private final Account[] mAccounts; + private final ParcelableAccount[] mAccounts; private long mAccountId; public AccountActionProvider(final Context context) { super(context); - mAccounts = Account.getAccounts(context, false, false); + mAccounts = ParcelableAccount.getAccounts(context, false, false); } @Override @@ -37,7 +37,7 @@ public class AccountActionProvider extends ActionProvider implements TwidereCons @Override public void onPrepareSubMenu(final SubMenu subMenu) { 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 Intent intent = new Intent(); 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++) { final MenuItem item = subMenu.getItem(i); final Intent intent = item.getIntent(); - final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT); + final ParcelableAccount account = intent.getParcelableExtra(EXTRA_ACCOUNT); if (account.account_id == mAccountId) { item.setChecked(true); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java index 3f815da55..9d8dbbb8a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/AccountPreferences.java @@ -46,7 +46,7 @@ public class AccountPreferences implements Constants { } 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); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/CustomTabConfiguration2.java b/twidere/src/main/java/org/mariotaku/twidere/model/CustomTabConfiguration2.java deleted file mode 100644 index 11be8cc1d..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/model/CustomTabConfiguration2.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.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 cls; - private final String secondaryFieldTextKey; - private final boolean singleTab; - - CustomTabConfiguration2(final Class 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 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 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 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 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> { - - public static final CustomTabConfigurationComparator SINGLETON = new CustomTabConfigurationComparator(); - - @Override - public int compare(final Entry lhs, - final Entry rhs) { - return lhs.getValue().getSortPosition() - rhs.getValue().getSortPosition(); - } - - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/DraftItem.java b/twidere/src/main/java/org/mariotaku/twidere/model/DraftItem.java index 14349b616..3a0f86e29 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/DraftItem.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/DraftItem.java @@ -80,7 +80,7 @@ public class DraftItem implements Parcelable { public DraftItem(final ParcelableStatusUpdate status) { _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; text = status.text; media = status.media; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/Account.java b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java similarity index 81% rename from twidere/src/main/java/org/mariotaku/twidere/model/Account.java rename to twidere/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java index c85a4baee..14e4edb50 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/Account.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableAccount.java @@ -27,8 +27,8 @@ import android.os.Parcelable; import android.support.annotation.NonNull; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.provider.TweetStore.Accounts; 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.shouldForceUsingPrivateAPIs; -public class Account implements Parcelable { +public class ParcelableAccount implements Parcelable { - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override - public Account createFromParcel(final Parcel in) { - return new Account(in); + public ParcelableAccount createFromParcel(final Parcel in) { + return new ParcelableAccount(in); } @Override - public Account[] newArray(final int size) { - return new Account[size]; + public ParcelableAccount[] newArray(final int size) { + return new ParcelableAccount[size]; } }; @@ -60,7 +60,7 @@ public class Account implements Parcelable { public final boolean is_activated; public final boolean is_dummy; - public Account(final Cursor cursor, final Indices indices) { + public ParcelableAccount(final Cursor cursor, final Indices indices) { is_dummy = false; screen_name = indices.screen_name != -1 ? cursor.getString(indices.screen_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; } - public Account(final Parcel source) { + public ParcelableAccount(final Parcel source) { is_dummy = source.readInt() == 1; is_activated = source.readInt() == 1; account_id = source.readLong(); @@ -82,7 +82,7 @@ public class Account implements Parcelable { color = source.readInt(); } - private Account() { + private ParcelableAccount() { is_dummy = true; screen_name = null; name = null; @@ -117,11 +117,11 @@ public class Account implements Parcelable { out.writeInt(color); } - public static Account dummyInstance() { - return new Account(); + public static ParcelableAccount dummyInstance() { + 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; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null); @@ -130,7 +130,7 @@ public class Account implements Parcelable { if (cur.getCount() > 0 && cur.moveToFirst()) { final Indices indices = new Indices(cur); cur.moveToFirst(); - return new Account(cur, indices); + return new ParcelableAccount(cur, indices); } } finally { cur.close(); @@ -139,7 +139,7 @@ public class Account implements Parcelable { return null; } - public static long[] getAccountIds(final Account[] accounts) { + public static long[] getAccountIds(final ParcelableAccount[] accounts) { final long[] ids = new long[accounts.length]; for (int i = 0, j = accounts.length; i < j; i++) { ids[i] = accounts[i].account_id; @@ -147,25 +147,25 @@ public class Account implements Parcelable { 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 List list = getAccountsList(context, activatedOnly, officialKeyOnly); - return list.toArray(new Account[list.size()]); + final List list = getAccountsList(context, activatedOnly, officialKeyOnly); + return list.toArray(new ParcelableAccount[list.size()]); } - public static Account[] getAccounts(final Context context, final long[] accountIds) { - if (context == null) return new Account[0]; - final String where = accountIds != null ? Where.in(new Column(Accounts.ACCOUNT_ID), + public static ParcelableAccount[] getAccounts(final Context context, final long[] accountIds) { + if (context == null) return new ParcelableAccount[0]; + final String where = accountIds != null ? Expression.in(new Column(Accounts.ACCOUNT_ID), new RawItemArray(accountIds)).getSQL() : null; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS_NO_CREDENTIALS, where, null, null); - if (cur == null) return new Account[0]; + if (cur == null) return new ParcelableAccount[0]; try { final Indices idx = new Indices(cur); cur.moveToFirst(); - final Account[] names = new Account[cur.getCount()]; + final ParcelableAccount[] names = new ParcelableAccount[cur.getCount()]; while (!cur.isAfterLast()) { - names[cur.getPosition()] = new Account(cur, idx); + names[cur.getPosition()] = new ParcelableAccount(cur, idx); cur.moveToNext(); } return names; @@ -174,14 +174,14 @@ public class Account implements Parcelable { } } - public static List getAccountsList(final Context context, final boolean activatedOnly) { + public static List getAccountsList(final Context context, final boolean activatedOnly) { return getAccountsList(context, activatedOnly, false); } - public static List getAccountsList(final Context context, final boolean activatedOnly, + public static List getAccountsList(final Context context, final boolean activatedOnly, final boolean officialKeyOnly) { if (context == null) return Collections.emptyList(); - final ArrayList accounts = new ArrayList<>(); + final ArrayList accounts = new ArrayList<>(); final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS_NO_CREDENTIALS, activatedOnly ? Accounts.IS_ACTIVATED + " = 1" : null, null, Accounts.SORT_POSITION); @@ -190,13 +190,13 @@ public class Account implements Parcelable { cur.moveToFirst(); while (!cur.isAfterLast()) { if (!officialKeyOnly) { - accounts.add(new Account(cur, indices)); + accounts.add(new ParcelableAccount(cur, indices)); } else { final String consumerKey = cur.getString(indices.consumer_key); final String consumerSecret = cur.getString(indices.consumer_secret); if (shouldForceUsingPrivateAPIs(context) || isOfficialConsumerKeySecret(context, consumerKey, consumerSecret)) { - accounts.add(new Account(cur, indices)); + accounts.add(new ParcelableAccount(cur, indices)); } } cur.moveToNext(); @@ -205,7 +205,7 @@ public class Account implements Parcelable { 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; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS, Accounts.ACCOUNT_ID + " = " + account_id, null, null); @@ -214,7 +214,7 @@ public class Account implements Parcelable { if (cur.getCount() > 0 && cur.moveToFirst()) { final Indices indices = new Indices(cur); cur.moveToFirst(); - return new AccountWithCredentials(cur, indices); + return new ParcelableAccountWithCredentials(cur, indices); } } finally { cur.close(); @@ -223,7 +223,7 @@ public class Account implements Parcelable { return null; } - public static class AccountWithCredentials extends Account { + public static class ParcelableAccountWithCredentials extends ParcelableAccount { public final int auth_type; public final String consumer_key, consumer_secret; @@ -232,7 +232,7 @@ public class Account implements Parcelable { public final String api_url_format; 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); auth_type = cursor.getInt(indices.auth_type); 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 + "}"; } - 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; final boolean isOAuth = account.auth_type == Accounts.AUTH_TYPE_OAUTH || account.auth_type == Accounts.AUTH_TYPE_XAUTH; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableStatusUpdate.java b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableStatusUpdate.java index 353036c35..2deac7c2e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableStatusUpdate.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/ParcelableStatusUpdate.java @@ -39,7 +39,7 @@ public class ParcelableStatusUpdate implements Parcelable { } }; - public final Account[] accounts; + public final ParcelableAccount[] accounts; public final ParcelableMediaUpdate[] media; public final String text; public final ParcelableLocation location; @@ -51,7 +51,7 @@ public class ParcelableStatusUpdate implements Parcelable { * ParcelableStatusUpdate.Builder instead. */ @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) { this.accounts = accounts; this.text = text; @@ -62,7 +62,7 @@ public class ParcelableStatusUpdate implements Parcelable { } 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; location = draft.location; media = draft.media; @@ -71,7 +71,7 @@ public class ParcelableStatusUpdate implements Parcelable { } public ParcelableStatusUpdate(final Parcel in) { - accounts = in.createTypedArray(Account.CREATOR); + accounts = in.createTypedArray(ParcelableAccount.CREATOR); text = in.readString(); location = in.readParcelable(ParcelableLocation.class.getClassLoader()); media = in.createTypedArray(ParcelableMediaUpdate.CREATOR); @@ -103,7 +103,7 @@ public class ParcelableStatusUpdate implements Parcelable { public static final class Builder { - private Account[] accounts; + private ParcelableAccount[] accounts; private String text; private ParcelableLocation location; private ParcelableMediaUpdate[] media; @@ -123,7 +123,7 @@ public class ParcelableStatusUpdate implements Parcelable { isPossiblySensitive(base.is_possibly_sensitive); } - public Builder accounts(final Account[] accounts) { + public Builder accounts(final ParcelableAccount[] accounts) { this.accounts = accounts; return this; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/AccountsListPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/AccountsListPreference.java index 55d8371df..e26b98195 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/AccountsListPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/AccountsListPreference.java @@ -36,8 +36,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.ImageView; -import android.widget.ImageView.ScaleType; import android.widget.Switch; import android.widget.TextView; @@ -47,7 +45,7 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; 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.util.ImageLoaderWrapper; import org.mariotaku.twidere.util.Utils; @@ -76,9 +74,9 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen a.recycle(); } - public void setAccountsData(final List accounts) { + public void setAccountsData(final List accounts) { removeAll(); - for (final Account account : accounts) { + for (final ParcelableAccount account : accounts) { final AccountItemPreference preference = new AccountItemPreference(getContext(), account, mSwitchKey, mSwitchDefault); setupPreference(preference, account); @@ -95,12 +93,12 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen 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, OnCheckedChangeListener, OnSharedPreferenceChangeListener, OnPreferenceClickListener, OnClickListener { - private final Account mAccount; + private final ParcelableAccount mAccount; private final SharedPreferences mSwitchPreference; private final ImageLoaderWrapper mImageLoader; @@ -108,7 +106,7 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen private final boolean mSwitchDefault; 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) { super(context); 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> { + private static class LoadAccountsTask extends AsyncTask> { private final AccountsListPreference mPreference; @@ -224,12 +222,12 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen } @Override - protected List doInBackground(final Void... params) { - return Account.getAccountsList(mPreference.getContext(), false); + protected List doInBackground(final Void... params) { + return ParcelableAccount.getAccountsList(mPreference.getContext(), false); } @Override - protected void onPostExecute(final List result) { + protected void onPostExecute(final List result) { mPreference.setAccountsData(result); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/AutoRefreshAccountsListPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/AutoRefreshAccountsListPreference.java index a6759f223..c060f14eb 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/AutoRefreshAccountsListPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/AutoRefreshAccountsListPreference.java @@ -25,7 +25,7 @@ import android.util.AttributeSet; import org.mariotaku.twidere.TwidereConstants; 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 { @@ -42,7 +42,7 @@ public class AutoRefreshAccountsListPreference extends AccountsListPreference im } @Override - protected void setupPreference(final AccountItemPreference preference, final Account account) { + protected void setupPreference(final AccountItemPreference preference, final ParcelableAccount account) { preference.setFragment(AccountRefreshSettingsFragment.class.getName()); final Bundle args = preference.getExtras(); args.putParcelable(EXTRA_ACCOUNT, account); diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationAccountsListPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationAccountsListPreference.java index ba0153019..3529b6846 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationAccountsListPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationAccountsListPreference.java @@ -25,7 +25,7 @@ import android.util.AttributeSet; import org.mariotaku.twidere.TwidereConstants; 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 { @@ -42,7 +42,7 @@ public class NotificationAccountsListPreference extends AccountsListPreference i } @Override - protected void setupPreference(final AccountItemPreference preference, final Account account) { + protected void setupPreference(final AccountItemPreference preference, final ParcelableAccount account) { preference.setFragment(AccountNotificationSettingsFragment.class.getName()); final Bundle args = preference.getExtras(); args.putParcelable(EXTRA_ACCOUNT, account); diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereCommandProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereCommandProvider.java index b9f30ea61..bf5c1c2c3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereCommandProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereCommandProvider.java @@ -146,7 +146,7 @@ public class TwidereCommandProvider extends ContentProvider implements Constants case CODE_REFRESH_HOME_TIMELINE: if (mTwitterWrapper.isHomeTimelineRefreshing()) return getEmptyCursor(); case CODE_REFRESH_MENTIONS: - if (mTwitterWrapper.isMentionsRefreshing()) return getEmptyCursor(); + if (mTwitterWrapper.isMentionsTimelineRefreshing()) return getEmptyCursor(); case CODE_REFRESH_INBOX: if (mTwitterWrapper.isReceivedDirectMessagesRefreshing()) return getEmptyCursor(); case CODE_REFRESH_OUTBOX: diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java index 8bbd0fb05..5415e4f31 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java @@ -591,7 +591,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta isAccountSpecific = true; break; } - case NOTIFICATION_ID_MENTIONS: { + case NOTIFICATION_ID_MENTIONS_TIMELINE: { mNewMentions.clear(); isAccountSpecific = true; break; @@ -889,7 +889,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta private Cursor getNotificationsCursor() { 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_MENTIONS, mNewMentions.size()}); + c.addRow(new Integer[]{NOTIFICATION_ID_MENTIONS_TIMELINE, mNewMentions.size()}); c.addRow(new Integer[]{NOTIFICATION_ID_DIRECT_MESSAGES, mNewMessages.size()}); return c; } @@ -898,7 +898,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta final MatrixCursor c = new MatrixCursor(TweetStore.Notifications.MATRIX_COLUMNS); if (id == NOTIFICATION_ID_HOME_TIMELINE) { 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()}); } else if (id == NOTIFICATION_ID_DIRECT_MESSAGES) { 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; // Add statuses that not filtered to list for future use. 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); for (final ContentValues value : values) { final ParcelableStatus status = new ParcelableStatus(value); @@ -1112,12 +1112,12 @@ public final class TwidereDataProvider extends ContentProvider implements Consta if (pref.isMentionsNotificationEnabled()) { final long accountId = pref.getAccountId(); 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.drawable.ic_stat_mention); } } - notifyUnreadCountChanged(NOTIFICATION_ID_MENTIONS); + notifyUnreadCountChanged(NOTIFICATION_ID_MENTIONS_TIMELINE); break; } case TABLE_ID_DIRECT_MESSAGES_INBOX: { diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java index 2512da855..b44141bab 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java @@ -45,7 +45,7 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.MainActivity; import org.mariotaku.twidere.activity.MainHondaJOJOActivity; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.model.Account; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.MediaUploadResult; import org.mariotaku.twidere.model.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableLocation; @@ -278,7 +278,7 @@ public class BackgroundOperationService extends IntentService implements Constan final List> result = updateStatus(builder, item); boolean failed = false; Exception exception = null; - final List failed_account_ids = ListUtils.fromArray(Account.getAccountIds(item.accounts)); + final List failed_account_ids = ListUtils.fromArray(ParcelableAccount.getAccountIds(item.accounts)); for (final SingleResponse response : result) { if (response.getData() == null) { @@ -446,7 +446,7 @@ public class BackgroundOperationService extends IntentService implements Constan } } } - for (final Account account : statusUpdate.accounts) { + for (final ParcelableAccount account : statusUpdate.accounts) { final Twitter twitter = getTwitterInstance(this, account.account_id, true, true); final StatusUpdate status = new StatusUpdate(shortenedText); status.setInReplyToStatusId(statusUpdate.in_reply_to_status_id); diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java b/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java index 998db280b..fea937f99 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java @@ -184,7 +184,7 @@ public class RefreshService extends Service implements Constants { } private int getMentions(final long[] accountIds, final long[] maxIds, final long[] sinceIds) { - return mTwitterWrapper.getMentionsAsync(accountIds, maxIds, sinceIds); + return mTwitterWrapper.getMentionsTimelineAsync(accountIds, maxIds, sinceIds); } private int getReceivedDirectMessages(final long[] accountIds, final long[] maxIds, final long[] sinceIds) { @@ -220,7 +220,7 @@ public class RefreshService extends Service implements Constants { } private boolean isMentionsRefreshing() { - return mTwitterWrapper.isMentionsRefreshing(); + return mTwitterWrapper.isMentionsTimelineRefreshing(); } private boolean isReceivedDirectMessagesRefreshing() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java index 43e10596b..1c5b6cffa 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/CacheUsersStatusesTask.java @@ -30,7 +30,7 @@ import android.content.Context; import com.twitter.Extractor; -import org.mariotaku.querybuilder.Where; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.provider.TweetStore.CachedHashtags; import org.mariotaku.twidere.provider.TweetStore.CachedStatuses; @@ -84,7 +84,7 @@ public class CacheUsersStatusesTask extends AsyncTask implemen final ContentValues filtered_users_values = new ContentValues(); filtered_users_values.put(Filters.Users.NAME, user.getName()); filtered_users_values.put(Filters.Users.SCREEN_NAME, user.getScreenName()); - final String filtered_users_where = Where.equals(Filters.Users.USER_ID, user.getId()).getSQL(); + final String filtered_users_where = Expression.equals(Filters.Users.USER_ID, user.getId()).getSQL(); resolver.update(Filters.Users.CONTENT_URI, filtered_users_values, filtered_users_where, null); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index a0f02ae9f..1e57616d3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -29,11 +29,11 @@ import android.net.Uri; import android.os.Bundle; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.RawItemArray; -import org.mariotaku.querybuilder.Where; import org.mariotaku.twidere.R; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.model.Account; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ListResponse; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableMediaUpdate; @@ -246,7 +246,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { return mGetLocalTrendsTaskId = mAsyncTaskManager.add(task, true); } - public int getMentionsAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) { + public int getMentionsTimelineAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) { mAsyncTaskManager.cancel(mGetMentionsTaskId); final GetMentionsTask task = new GetMentionsTask(accountIds, max_ids, since_ids); return mGetMentionsTaskId = mAsyncTaskManager.add(task, true); @@ -302,7 +302,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { || mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_TRENDS); } - public boolean isMentionsRefreshing() { + public boolean isMentionsTimelineRefreshing() { return mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_GET_MENTIONS) || mAsyncTaskManager.hasRunningTasksForTag(TASK_TAG_STORE_MENTIONS); } @@ -325,7 +325,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public int refreshAll(final long[] accountIds) { if (mPreferences.getBoolean(KEY_HOME_REFRESH_MENTIONS, HomeRefreshContentPreference.DEFAULT_ENABLE_MENTIONS)) { final long[] sinceIds = getNewestStatusIdsFromDatabase(mContext, Mentions.CONTENT_URI, accountIds); - getMentionsAsync(accountIds, null, sinceIds); + getMentionsTimelineAsync(accountIds, null, sinceIds); } if (mPreferences.getBoolean(KEY_HOME_REFRESH_DIRECT_MESSAGES, HomeRefreshContentPreference.DEFAULT_ENABLE_DIRECT_MESSAGES)) { @@ -398,7 +398,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final ParcelableMediaUpdate[] media, final long inReplyToStatusId, final boolean isPossiblySensitive) { final ParcelableStatusUpdate.Builder builder = new ParcelableStatusUpdate.Builder(); - builder.accounts(Account.getAccounts(mContext, accountIds)); + builder.accounts(ParcelableAccount.getAccounts(mContext, accountIds)); builder.text(text); builder.location(location); builder.media(media); @@ -693,15 +693,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper { try { final User user = twitter.createBlock(user_id); for (final Uri uri : STATUSES_URIS) { - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, account_id), - Where.equals(Statuses.USER_ID, user_id)); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), + Expression.equals(Statuses.USER_ID, user_id)); mResolver.delete(uri, where.getSQL(), null); } // I bet you don't want to see this user in your auto // complete // list. - final Where where = Where.equals(CachedUsers.USER_ID, user_id); + final Expression where = Expression.equals(CachedUsers.USER_ID, user_id); mResolver.delete(CachedUsers.CONTENT_URI, where.getSQL(), null); return SingleResponse.getInstance(user, null); } catch (final TwitterException e) { @@ -742,8 +742,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (twitter == null) return SingleResponse.getInstance(); try { final User user = twitter.createMute(mUserId); - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, mAccountId), - Where.equals(Statuses.USER_ID, mUserId)); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, mAccountId), + Expression.equals(Statuses.USER_ID, mUserId)); mResolver.delete(Statuses.CONTENT_URI, where.getSQL(), null); return SingleResponse.getInstance(user, null); @@ -788,9 +788,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final twitter4j.Status status = twitter.createFavorite(status_id); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, true); - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, account_id), - Where.or(Where.equals(Statuses.STATUS_ID, status_id), - Where.equals(Statuses.RETWEET_ID, status_id))); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), + Expression.or(Expression.equals(Statuses.STATUS_ID, status_id), + Expression.equals(Statuses.RETWEET_ID, status_id))); for (final Uri uri : TweetStore.STATUSES_URIS) { mResolver.update(uri, values, where.getSQL(), null); } @@ -1310,8 +1310,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { final twitter4j.Status status = twitter.destroyFavorite(status_id); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, 0); - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, account_id), - Where.or(Where.equals(Statuses.STATUS_ID, status_id), Where.equals(Statuses.RETWEET_ID, status_id))); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), + Expression.or(Expression.equals(Statuses.STATUS_ID, status_id), Expression.equals(Statuses.RETWEET_ID, status_id))); for (final Uri uri : TweetStore.STATUSES_URIS) { mResolver.update(uri, values, where.getSQL(), null); } @@ -1366,9 +1366,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { try { final User user = twitter.destroyFriendship(user_id); // remove user tweets and retweets - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, account_id), - Where.or(Where.equals(Statuses.USER_ID, user_id), - Where.equals(Statuses.RETWEETED_BY_USER_ID, user_id))); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), + Expression.or(Expression.equals(Statuses.USER_ID, user_id), + Expression.equals(Statuses.RETWEETED_BY_USER_ID, user_id))); mResolver.delete(Statuses.CONTENT_URI, where.getSQL(), null); return SingleResponse.getInstance(user, null); } catch (final TwitterException e) { @@ -1943,8 +1943,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (result != null) { final String user_id_where = ListUtils.toString(result.list, ',', false); for (final Uri uri : STATUSES_URIS) { - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, account_id), - new Where(String.format(Locale.ROOT, "%s IN (%s)", Statuses.USER_ID, user_id_where))); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id), + new Expression(String.format(Locale.ROOT, "%s IN (%s)", Statuses.USER_ID, user_id_where))); mResolver.delete(uri, where.getSQL(), null); } mMessagesManager.showInfoMessage(R.string.reported_users_for_spam, false); @@ -2043,9 +2043,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { for (final Uri uri : STATUSES_URIS) { mResolver.update(uri, values, where, null); } - final Intent intent = new Intent(BROADCAST_RETWEET_CHANGED); + final Intent intent = new Intent(BROADCAST_STATUS_RETWEETED); intent.putExtra(EXTRA_STATUS_ID, status_id); - intent.putExtra(EXTRA_RETWEETED, true); mContext.sendBroadcast(intent); mMessagesManager.showOkMessage(R.string.status_retweeted, false); } else { @@ -2090,8 +2089,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { // Delete all rows conflicting before new data inserted. { - final Where deleteWhere = Where.and(Where.equals(DirectMessages.ACCOUNT_ID, accountId), - Where.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds))); + final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId), + Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds))); final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, false)); mResolver.delete(deleteUri, deleteWhere.getSQL(), null); @@ -2211,9 +2210,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper { statusIds[i] = status.getId(); } // Delete all rows conflicting before new data inserted. - final Where accountWhere = Where.equals(Statuses.ACCOUNT_ID, accountId); - final Where statusWhere = Where.in(new Column(Statuses.STATUS_ID), new RawItemArray(statusIds)); - final String deleteWhere = Where.and(accountWhere, statusWhere).getSQL(); + final Expression accountWhere = Expression.equals(Statuses.ACCOUNT_ID, accountId); + final Expression statusWhere = Expression.in(new Column(Statuses.STATUS_ID), new RawItemArray(statusIds)); + final String deleteWhere = Expression.and(accountWhere, statusWhere).getSQL(); final Uri deleteUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, false)); final int rowsDeleted = mResolver.delete(deleteUri, deleteWhere, null); // UCD @@ -2233,8 +2232,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { if (insertGap) { final ContentValues gapValue = new ContentValues(); gapValue.put(Statuses.IS_GAP, 1); - final Where where = Where.and(Where.equals(Statuses.ACCOUNT_ID, accountId), - Where.equals(Statuses.STATUS_ID, minId)); + final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId), + Expression.equals(Statuses.STATUS_ID, minId)); final Uri updateUri = appendQueryParameters(uri, new NameValuePairImpl(QUERY_PARAM_NOTIFY, true)); mResolver.update(updateUri, gapValue, where.getSQL(), null); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java b/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java index 9b7283b37..9aba1fdf3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ContentValuesCreator.java @@ -25,7 +25,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.mariotaku.jsonserializer.JSONSerializer; import org.mariotaku.twidere.TwidereConstants; -import org.mariotaku.twidere.model.Account; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableMedia; @@ -326,7 +326,7 @@ public final class ContentValuesCreator implements TwidereConstants { } public static ContentValues makeStatusDraftContentValues(final ParcelableStatusUpdate status) { - return makeStatusDraftContentValues(status, Account.getAccountIds(status.accounts)); + return makeStatusDraftContentValues(status, ParcelableAccount.getAccountIds(status.accounts)); } public static ContentValues makeStatusDraftContentValues(final ParcelableStatusUpdate status, diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java index fbd0e2f55..5b6d1bef7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/CustomTabUtils.java @@ -36,12 +36,10 @@ 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.InvalidTabFragment; import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment; import org.mariotaku.twidere.fragment.support.RetweetsOfMeFragment; import org.mariotaku.twidere.fragment.support.SearchStatusesFragment; -import org.mariotaku.twidere.fragment.support.StaggeredHomeTimelineFragment; import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment; import org.mariotaku.twidere.fragment.support.UserFavoritesFragment; import org.mariotaku.twidere.fragment.support.UserListTimelineFragment; @@ -102,10 +100,6 @@ public class CustomTabUtils implements Constants { RetweetsOfMeFragment.class, R.string.retweets_of_me, R.drawable.ic_action_retweet, CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_NONE, 10)); if (Utils.hasStaggeredTimeline()) { - CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_STAGGERED_HOME_TIMELINE, new CustomTabConfiguration( - StaggeredHomeTimelineFragment.class, R.string.staggered_home_timeline, - R.drawable.ic_action_view_quilt, CustomTabConfiguration.ACCOUNT_OPTIONAL, - CustomTabConfiguration.FIELD_TYPE_NONE, 11, false)); } CUSTOM_TABS_ICON_NAME_MAP.put("accounts", R.drawable.ic_action_accounts); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/ImageLoaderWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/ImageLoaderWrapper.java index e7670ccde..5b03ba7aa 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/ImageLoaderWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/ImageLoaderWrapper.java @@ -20,7 +20,6 @@ package org.mariotaku.twidere.util; import android.graphics.Bitmap; -import android.text.TextUtils; import android.widget.ImageView; import com.nostra13.universalimageloader.core.DisplayImageOptions; @@ -33,7 +32,7 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.util.imageloader.AccountExtra; import org.mariotaku.twidere.util.imageloader.OvalBitmapDisplayer; -import static org.mariotaku.twidere.util.Utils.getBestBannerType; +import static org.mariotaku.twidere.util.Utils.getBestBannerUrl; public class ImageLoaderWrapper implements Constants { @@ -104,10 +103,17 @@ public class ImageLoaderWrapper implements Constants { mImageLoader.displayImage(url, view, b.build(), loadingHandler, loadingHandler); } - public void displayProfileBanner(final ImageView view, final String base_url, final int width) { - final String type = getBestBannerType(width); - final String url = TextUtils.isEmpty(base_url) ? null : base_url + "/" + type; - mImageLoader.displayImage(url, view, mBannerDisplayOptions); + public void displayProfileBanner(final ImageView view, final String url, + final ImageLoadingListener listener) { + mImageLoader.displayImage(url, view, mBannerDisplayOptions, listener); + } + + public void displayProfileBanner(final ImageView view, final String url) { + displayProfileBanner(view, url, null); + } + + public void displayProfileBanner(final ImageView view, final String baseUrl, final int width) { + displayProfileBanner(view, getBestBannerUrl(baseUrl, width)); } public void displayProfileImage(final ImageView view, final String url) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java b/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java index 5e2d2e86f..7cec10f2e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MultiSelectEventHandler.java @@ -36,7 +36,7 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.support.BaseSupportActivity; import org.mariotaku.twidere.app.TwidereApplication; import org.mariotaku.twidere.menu.AccountActionProvider; -import org.mariotaku.twidere.model.Account; +import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.provider.TweetStore.Filters; @@ -179,7 +179,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback, if (item.getGroupId() == AccountActionProvider.MENU_GROUP) { final Intent intent = item.getIntent(); if (intent == null || !intent.hasExtra(EXTRA_ACCOUNT)) return false; - final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT); + final ParcelableAccount account = intent.getParcelableExtra(EXTRA_ACCOUNT); mMultiSelectManager.setAccountId(account.account_id); if (mAccountActionProvider != null) { mAccountActionProvider.setAccountId(account.account_id); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereQueryBuilder.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereQueryBuilder.java index 184c11e2a..393142f23 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwidereQueryBuilder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwidereQueryBuilder.java @@ -21,11 +21,11 @@ package org.mariotaku.twidere.util; import org.mariotaku.querybuilder.Columns; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.SQLQueryBuilder; import org.mariotaku.querybuilder.Selectable; import org.mariotaku.querybuilder.Tables; -import org.mariotaku.querybuilder.Where; import org.mariotaku.querybuilder.query.SQLSelectQuery; import org.mariotaku.twidere.provider.TweetStore.DirectMessages; import org.mariotaku.twidere.provider.TweetStore.DirectMessages.Conversation; @@ -42,16 +42,16 @@ public class TwidereQueryBuilder { final Selectable select = Utils.getColumnsFromProjection(projection); final SQLSelectQuery.Builder qb = SQLQueryBuilder.select(select); qb.from(new Tables(DirectMessages.TABLE_NAME)); - final Where accountIdWhere = Where.equals(DirectMessages.ACCOUNT_ID, account_id); - final Where incomingWhere = Where.and(Where.notEquals(DirectMessages.IS_OUTGOING, 1), - Where.equals(DirectMessages.SENDER_ID, conversationId)); - final Where outgoingWhere = Where.and(Where.equals(DirectMessages.IS_OUTGOING, 1), - Where.equals(DirectMessages.RECIPIENT_ID, conversationId)); - final Where conversationWhere = Where.or(incomingWhere, outgoingWhere); + final Expression accountIdWhere = Expression.equals(DirectMessages.ACCOUNT_ID, account_id); + final Expression incomingWhere = Expression.and(Expression.notEquals(DirectMessages.IS_OUTGOING, 1), + Expression.equals(DirectMessages.SENDER_ID, conversationId)); + final Expression outgoingWhere = Expression.and(Expression.equals(DirectMessages.IS_OUTGOING, 1), + Expression.equals(DirectMessages.RECIPIENT_ID, conversationId)); + final Expression conversationWhere = Expression.or(incomingWhere, outgoingWhere); if (selection != null) { - qb.where(Where.and(accountIdWhere, conversationWhere, new Where(selection))); + qb.where(Expression.and(accountIdWhere, conversationWhere, new Expression(selection))); } else { - qb.where(Where.and(accountIdWhere, conversationWhere)); + qb.where(Expression.and(accountIdWhere, conversationWhere)); } qb.orderBy(new OrderBy(sortOrder != null ? sortOrder : Conversation.DEFAULT_SORT_ORDER)); return qb.build().getSQL(); @@ -63,15 +63,15 @@ public class TwidereQueryBuilder { final SQLSelectQuery.Builder qb = SQLQueryBuilder.select(select); qb.select(select); qb.from(new Tables(DirectMessages.TABLE_NAME)); - final Where accountIdWhere = Where.equals(DirectMessages.ACCOUNT_ID, account_id); - final Where incomingWhere = Where.and(Where.notEquals(DirectMessages.IS_OUTGOING, 1), - Where.equals(new Column(DirectMessages.SENDER_SCREEN_NAME), screen_name)); - final Where outgoingWhere = Where.and(Where.equals(DirectMessages.IS_OUTGOING, 1), - Where.equals(new Column(DirectMessages.RECIPIENT_SCREEN_NAME), screen_name)); + final Expression accountIdWhere = Expression.equals(DirectMessages.ACCOUNT_ID, account_id); + final Expression incomingWhere = Expression.and(Expression.notEquals(DirectMessages.IS_OUTGOING, 1), + Expression.equals(new Column(DirectMessages.SENDER_SCREEN_NAME), screen_name)); + final Expression outgoingWhere = Expression.and(Expression.equals(DirectMessages.IS_OUTGOING, 1), + Expression.equals(new Column(DirectMessages.RECIPIENT_SCREEN_NAME), screen_name)); if (selection != null) { - qb.where(Where.and(accountIdWhere, incomingWhere, outgoingWhere, new Where(selection))); + qb.where(Expression.and(accountIdWhere, incomingWhere, outgoingWhere, new Expression(selection))); } else { - qb.where(Where.and(accountIdWhere, incomingWhere, outgoingWhere)); + qb.where(Expression.and(accountIdWhere, incomingWhere, outgoingWhere)); } qb.orderBy(new OrderBy(sortOrder != null ? sortOrder : Conversation.DEFAULT_SORT_ORDER)); return qb.build().getSQL(); @@ -127,20 +127,20 @@ public class TwidereQueryBuilder { conversationIds.select(new Columns(new Column(DirectMessages.MESSAGE_ID), new Column( DirectMessages.SENDER_ID, ConversationEntries.CONVERSATION_ID))); conversationIds.from(new Tables(Inbox.TABLE_NAME)); - conversationIds.where(Where.in(new Column(DirectMessages.MESSAGE_ID), recent_inbox_msg_ids.build())); + conversationIds.where(Expression.in(new Column(DirectMessages.MESSAGE_ID), recent_inbox_msg_ids.build())); conversationIds.union(); conversationIds.select(new Columns(new Column(DirectMessages.MESSAGE_ID), new Column( DirectMessages.RECIPIENT_ID, ConversationEntries.CONVERSATION_ID))); conversationIds.from(new Tables(Outbox.TABLE_NAME)); - conversationIds.where(Where.in(new Column(DirectMessages.MESSAGE_ID), recent_outbox_msg_ids.build())); + conversationIds.where(Expression.in(new Column(DirectMessages.MESSAGE_ID), recent_outbox_msg_ids.build())); final SQLSelectQuery.Builder groupedConversationIds = new SQLSelectQuery.Builder(); groupedConversationIds.select(new Column(DirectMessages.MESSAGE_ID)); groupedConversationIds.from(conversationIds.build()); groupedConversationIds.groupBy(new Column(ConversationEntries.CONVERSATION_ID)); - final Where groupedWhere = Where.in(new Column(DirectMessages.MESSAGE_ID), groupedConversationIds.build()); - final Where where; + final Expression groupedWhere = Expression.in(new Column(DirectMessages.MESSAGE_ID), groupedConversationIds.build()); + final Expression where; if (selection != null) { - where = Where.and(groupedWhere, new Where(selection)); + where = Expression.and(groupedWhere, new Expression(selection)); } else { where = groupedWhere; } @@ -164,12 +164,12 @@ public class TwidereQueryBuilder { final Selectable select = Utils.getColumnsFromProjection(projection); qb.select(select).from(new Tables(DirectMessages.Inbox.TABLE_NAME)); if (selection != null) { - qb.where(new Where(selection)); + qb.where(new Expression(selection)); } qb.union(); qb.select(select).from(new Tables(DirectMessages.Outbox.TABLE_NAME)); if (selection != null) { - qb.where(new Where(selection)); + qb.where(new Expression(selection)); } qb.orderBy(new OrderBy(sortOrder != null ? sortOrder : DirectMessages.DEFAULT_SORT_ORDER)); return qb.build(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java index 81cb98357..78a56586d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -102,8 +102,6 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; -import com.etsy.android.grid.StaggeredGridView; - import org.apache.http.NameValuePair; import org.json.JSONException; import org.mariotaku.gallery3d.ImageViewerGLActivity; @@ -112,11 +110,13 @@ import org.mariotaku.menucomponent.internal.menu.MenuUtils; import org.mariotaku.querybuilder.AllColumns; import org.mariotaku.querybuilder.Columns; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.OrderBy; import org.mariotaku.querybuilder.RawItemArray; +import org.mariotaku.querybuilder.SQLQueryBuilder; import org.mariotaku.querybuilder.Selectable; +import org.mariotaku.querybuilder.Table; import org.mariotaku.querybuilder.Tables; -import org.mariotaku.querybuilder.Where; import org.mariotaku.querybuilder.query.SQLSelectQuery; import org.mariotaku.refreshnow.widget.RefreshNowListView; import org.mariotaku.twidere.BuildConfig; @@ -154,9 +154,9 @@ import org.mariotaku.twidere.fragment.support.UserMentionsFragment; import org.mariotaku.twidere.fragment.support.UserTimelineFragment; import org.mariotaku.twidere.fragment.support.UsersListFragment; import org.mariotaku.twidere.graphic.PaddingDrawable; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.AccountWithCredentials; import org.mariotaku.twidere.model.AccountPreferences; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials; import org.mariotaku.twidere.model.ParcelableDirectMessage; import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableStatus; @@ -469,10 +469,10 @@ public final class Utils implements Constants, TwitterConstants { public static String buildActivatedStatsWhereClause(final Context context, final String selection) { if (context == null) return null; final long[] account_ids = getActivatedAccountIds(context); - final Where accountWhere = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids)); - final Where where; + final Expression accountWhere = Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids)); + final Expression where; if (selection != null) { - where = Where.and(accountWhere, new Where(selection)); + where = Expression.and(accountWhere, new Expression(selection)); } else { where = accountWhere; } @@ -489,50 +489,48 @@ public final class Utils implements Constants, TwitterConstants { return builder.build(); } - public static String buildStatusFilterWhereClause(final String table, final String selection, - final boolean enableInRts) { + public static Expression buildStatusFilterWhereClause(final String table, final Expression extraSelection, + final boolean enableInRts) { if (table == null) return null; - final StringBuilder builder = new StringBuilder(); - if (selection != null) { - builder.append(selection); - builder.append(" AND "); - } - builder.append(Statuses._ID + " NOT IN ( "); - builder.append("SELECT DISTINCT " + table + "." + Statuses._ID + " FROM " + table); - builder.append(" WHERE " + table + "." + Statuses.USER_ID + " IN ( SELECT " + Filters.Users.TABLE_NAME + "." - + Filters.Users.USER_ID + " FROM " + Filters.Users.TABLE_NAME + " )"); + final SQLSelectQuery filteredUsersQuery = SQLQueryBuilder + .select(new Column(new Table(Filters.Users.TABLE_NAME), Filters.Users.USER_ID)) + .from(new Tables(Filters.Users.TABLE_NAME)) + .build(); + final Expression filteredUsersWhere; if (enableInRts) { - builder.append(" OR " + table + "." + Statuses.RETWEETED_BY_USER_ID + " IN ( SELECT " - + Filters.Users.TABLE_NAME + "." + Filters.Users.USER_ID + " FROM " + Filters.Users.TABLE_NAME - + " )"); + filteredUsersWhere = Expression.or( + Expression.in(new Column(new Table(table), Statuses.USER_ID), filteredUsersQuery), + Expression.in(new Column(new Table(table), Statuses.RETWEETED_BY_USER_ID), filteredUsersQuery)); + } else { + filteredUsersWhere = Expression.in(new Column(new Table(table), Statuses.USER_ID), filteredUsersQuery); } - builder.append(" AND " + table + "." + Statuses.IS_GAP + " IS NULL"); - builder.append(" OR " + table + "." + Statuses.IS_GAP + " == 0"); - builder.append(" UNION "); - builder.append("SELECT DISTINCT " + table + "." + Statuses._ID + " FROM " + table + ", " - + Filters.Sources.TABLE_NAME); - builder.append(" WHERE " + table + "." + Statuses.SOURCE + " LIKE '%>'||" + Filters.Sources.TABLE_NAME + "." - + Filters.Sources.VALUE + "||'%'"); - builder.append(" AND " + table + "." + Statuses.IS_GAP + " IS NULL"); - builder.append(" OR " + table + "." + Statuses.IS_GAP + " == 0"); - builder.append(" UNION "); - builder.append("SELECT DISTINCT " + table + "." + Statuses._ID + " FROM " + table + ", " - + Filters.Keywords.TABLE_NAME); - builder.append(" WHERE " + table + "." + Statuses.TEXT_PLAIN + " LIKE '%'||" + Filters.Keywords.TABLE_NAME - + "." + Filters.Keywords.VALUE + "||'%'"); - builder.append(" AND " + table + "." + Statuses.IS_GAP + " IS NULL"); - builder.append(" OR " + table + "." + Statuses.IS_GAP + " == 0"); - builder.append(" UNION "); - builder.append("SELECT DISTINCT " + table + "." + Statuses._ID + " FROM " + table + ", " - + Filters.Links.TABLE_NAME); - builder.append(" WHERE " + table + "." + Statuses.TEXT_HTML + " LIKE '%%'"); - builder.append(" OR " + table + "." + Statuses.TEXT_HTML + " LIKE '%>%'||" + Filters.Links.TABLE_NAME + "." - + Filters.Links.VALUE + "||'%%'"); - builder.append(" AND " + table + "." + Statuses.IS_GAP + " IS NULL"); - builder.append(" OR " + table + "." + Statuses.IS_GAP + " == 0"); - builder.append(" )"); - return builder.toString(); + final SQLSelectQuery.Builder filteredIdsQueryBuilder = SQLQueryBuilder + .select(true, new Column(new Table(table), Statuses._ID)) + .from(new Tables(table)) + .where(filteredUsersWhere) + .union() + .select(true, new Columns(new Column(new Table(table), Statuses._ID))) + .from(new Tables(table, Filters.Sources.TABLE_NAME)) + .where(Expression.like(new Column(new Table(table), Statuses.SOURCE), + "%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'%")) + .union() + .select(true, new Columns(new Column(new Table(table), Statuses._ID))) + .from(new Tables(table, Filters.Keywords.TABLE_NAME)) + .where(Expression.like(new Column(new Table(table), Statuses.TEXT_PLAIN), + "%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%")) + .union() + .select(true, new Columns(new Column(new Table(table), Statuses._ID))) + .from(new Tables(table, Filters.Links.TABLE_NAME)) + .where(Expression.like(new Column(new Table(table), Statuses.SOURCE), + "%>%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%%")); + final Expression filterExpression = Expression.or( + Expression.notIn(new Column(new Table(table), Statuses._ID), filteredIdsQueryBuilder.build()), + Expression.equals(new Column(new Table(table), Statuses.IS_GAP), 1) + ); + if (extraSelection != null) { + return Expression.and(filterExpression, extraSelection); + } + return filterExpression; } public static int calculateInSampleSize(final int width, final int height, final int preferredWidth, @@ -569,24 +567,24 @@ public final class Utils implements Constants, TwitterConstants { continue; } final String table = getTableNameByUri(uri); - final Where account_where = new Where(Statuses.ACCOUNT_ID + " = " + account_id); + final Expression account_where = new Expression(Statuses.ACCOUNT_ID + " = " + account_id); final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder(); qb.select(new Column(Statuses._ID)).from(new Tables(table)); - qb.where(new Where(Statuses.ACCOUNT_ID + " = " + account_id)); + qb.where(new Expression(Statuses.ACCOUNT_ID + " = " + account_id)); qb.orderBy(new OrderBy(Statuses.STATUS_ID + " DESC")); qb.limit(itemLimit); - final Where where = Where.and(Where.notIn(new Column(Statuses._ID), qb.build()), account_where); + final Expression where = Expression.and(Expression.notIn(new Column(Statuses._ID), qb.build()), account_where); resolver.delete(uri, where.getSQL(), null); } for (final Uri uri : DIRECT_MESSAGES_URIS) { final String table = getTableNameByUri(uri); - final Where account_where = new Where(DirectMessages.ACCOUNT_ID + " = " + account_id); + final Expression account_where = new Expression(DirectMessages.ACCOUNT_ID + " = " + account_id); final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder(); qb.select(new Column(DirectMessages._ID)).from(new Tables(table)); - qb.where(new Where(DirectMessages.ACCOUNT_ID + " = " + account_id)); + qb.where(new Expression(DirectMessages.ACCOUNT_ID + " = " + account_id)); qb.orderBy(new OrderBy(DirectMessages.MESSAGE_ID + " DESC")); qb.limit(itemLimit); - final Where where = Where.and(Where.notIn(new Column(DirectMessages._ID), qb.build()), account_where); + final Expression where = Expression.and(Expression.notIn(new Column(DirectMessages._ID), qb.build()), account_where); resolver.delete(uri, where.getSQL(), null); } } @@ -598,7 +596,7 @@ public final class Utils implements Constants, TwitterConstants { qb.from(new Tables(table)); qb.orderBy(new OrderBy(BaseColumns._ID + " DESC")); qb.limit(itemLimit * 20); - final Where where = Where.notIn(new Column(BaseColumns._ID), qb.build()); + final Expression where = Expression.notIn(new Column(BaseColumns._ID), qb.build()); resolver.delete(uri, where.getSQL(), null); } } @@ -632,20 +630,6 @@ public final class Utils implements Constants, TwitterConstants { // Utils.scrollListToPosition(view, position, offset); } - public static void clearListViewChoices(final StaggeredGridView view) { - if (view == null) return; - final ListAdapter adapter = view.getAdapter(); - if (adapter == null) return; - view.clearChoices(); - view.setChoiceMode(AbsListView.CHOICE_MODE_NONE); - view.invalidateViews(); - // Workaround for Android bug - // http://stackoverflow.com/questions/9754170/listview-selection-remains-persistent-after-exiting-choice-mode - // final int position = view.getFirstVisiblePosition(); - // view.setAdapter(adapter); - // Utils.scrollListToPosition(view, position); - } - public static boolean closeSilently(final Closeable c) { if (c == null) return false; try { @@ -1313,7 +1297,7 @@ public final class Utils implements Constants, TwitterConstants { public static int[] getAccountColors(final Context context, final long[] accountIds) { if (context == null || accountIds == null) return new int[0]; final String[] cols = new String[]{Accounts.ACCOUNT_ID, Accounts.COLOR}; - final String where = Where.in(new Column(Accounts.ACCOUNT_ID), new RawItemArray(accountIds)).getSQL(); + final String where = Expression.in(new Column(Accounts.ACCOUNT_ID), new RawItemArray(accountIds)).getSQL(); final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, cols, where, null, null); if (cur == null) return new int[0]; @@ -1398,7 +1382,7 @@ public final class Utils implements Constants, TwitterConstants { public static String[] getAccountNames(final Context context, final long[] accountIds) { if (context == null) return new String[0]; final String[] cols = new String[]{Accounts.NAME}; - 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; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, cols, where, null, null); @@ -1456,7 +1440,7 @@ public final class Utils implements Constants, TwitterConstants { final boolean includeAtChar) { if (context == null) return new String[0]; final String[] cols = new String[]{Accounts.SCREEN_NAME}; - 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; final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, cols, where, null, null); @@ -1498,8 +1482,8 @@ public final class Utils implements Constants, TwitterConstants { if (context == null) return 0; final ContentResolver resolver = context.getContentResolver(); final Cursor cur = ContentResolverUtils.query(resolver, uri, new String[]{Statuses.STATUS_ID}, - buildStatusFilterWhereClause(getTableNameByUri(uri), null, shouldEnableFiltersForRTs(context)), null, - null); + buildStatusFilterWhereClause(getTableNameByUri(uri), null, shouldEnableFiltersForRTs(context)).getSQL(), + null, null); if (cur == null) return 0; try { return cur.getCount(); @@ -1512,8 +1496,8 @@ public final class Utils implements Constants, TwitterConstants { if (context == null) return new long[0]; final ContentResolver resolver = context.getContentResolver(); final Cursor cur = ContentResolverUtils.query(resolver, uri, new String[]{Statuses.STATUS_ID}, - buildStatusFilterWhereClause(getTableNameByUri(uri), null, shouldEnableFiltersForRTs(context)), null, - null); + buildStatusFilterWhereClause(getTableNameByUri(uri), null, shouldEnableFiltersForRTs(context)).getSQL(), + null, null); if (cur == null) return new long[0]; final long[] ids = new long[cur.getCount()]; cur.moveToFirst(); @@ -1552,6 +1536,11 @@ public final class Utils implements Constants, TwitterConstants { return sb.toString(); } + public static String getBestBannerUrl(final String baseUrl, final int width) { + final String type = getBestBannerType(width); + return TextUtils.isEmpty(baseUrl) ? null : baseUrl + "/" + type; + } + public static String getBestBannerType(final int width) { if (width <= 320) return "mobile"; @@ -2288,7 +2277,7 @@ public final class Utils implements Constants, TwitterConstants { return date.getTime(); } - public static Authorization getTwitterAuthorization(final Context context, final AccountWithCredentials account) { + public static Authorization getTwitterAuthorization(final Context context, final ParcelableAccountWithCredentials account) { if (context == null || account == null) return null; switch (account.auth_type) { case Accounts.AUTH_TYPE_OAUTH: @@ -2342,7 +2331,7 @@ public final class Utils implements Constants, TwitterConstants { public static Authorization getTwitterAuthorization(final Context context, final long accountId) { - final String where = Where.equals(new Column(Accounts.ACCOUNT_ID), accountId).getSQL(); + final String where = Expression.equals(new Column(Accounts.ACCOUNT_ID), accountId).getSQL(); final Cursor c = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS, where, null, null); if (c == null) return null; @@ -2468,7 +2457,7 @@ public final class Utils implements Constants, TwitterConstants { final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false); // Here I use old consumer key/secret because it's default key for older // versions - final String where = Where.equals(new Column(Accounts.ACCOUNT_ID), accountId).getSQL(); + final String where = Expression.equals(new Column(Accounts.ACCOUNT_ID), accountId).getSQL(); final Cursor c = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI, Accounts.COLUMNS, where, null, null); if (c == null) return null; @@ -2596,7 +2585,7 @@ public final class Utils implements Constants, TwitterConstants { Accounts.COLUMNS, null, null, null); if (cur == null) return false; final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_key_secret); - final Account.Indices indices = new Account.Indices(cur); + final ParcelableAccount.Indices indices = new ParcelableAccount.Indices(cur); cur.moveToFirst(); try { while (!cur.isAfterLast()) { @@ -2827,7 +2816,7 @@ public final class Utils implements Constants, TwitterConstants { public static boolean isOfficialKeyAccount(final Context context, final long accountId) { if (context == null) return false; final String[] projection = {Accounts.CONSUMER_KEY, Accounts.CONSUMER_SECRET}; - final String selection = Where.equals(Accounts.ACCOUNT_ID, accountId).getSQL(); + final String selection = Expression.equals(Accounts.ACCOUNT_ID, accountId).getSQL(); final Cursor c = context.getContentResolver().query(Accounts.CONTENT_URI, projection, selection, null, null); try { if (c.moveToPosition(0)) @@ -3544,8 +3533,8 @@ public final class Utils implements Constants, TwitterConstants { } final MenuItem translate = menu.findItem(MENU_TRANSLATE); if (translate != null) { - final AccountWithCredentials account = Account.getAccountWithCredentials(context, status.account_id); - final boolean isOfficialKey = AccountWithCredentials.isOfficialCredentials(context, account); + final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(context, status.account_id); + final boolean isOfficialKey = ParcelableAccountWithCredentials.isOfficialCredentials(context, account); setMenuItemAvailability(menu, MENU_TRANSLATE, isOfficialKey); } menu.removeGroup(MENU_GROUP_STATUS_EXTENSION); @@ -3975,7 +3964,7 @@ public final class Utils implements Constants, TwitterConstants { public static boolean isFilteringUser(Context context, long userId) { final ContentResolver cr = context.getContentResolver(); - final Where where = Where.equals(Users.USER_ID, userId); + final Expression where = Expression.equals(Users.USER_ID, userId); final Cursor c = cr.query(Users.CONTENT_URI, new String[0], where.getSQL(), null, null); try { return c.getCount() > 0; @@ -3987,8 +3976,8 @@ public final class Utils implements Constants, TwitterConstants { public static ParcelableUser getUserForConversation(Context context, long accountId, long conversationId) { final ContentResolver cr = context.getContentResolver(); - final Where where = Where.and(Where.equals(ConversationEntries.ACCOUNT_ID, accountId), - Where.equals(ConversationEntries.CONVERSATION_ID, conversationId)); + final Expression where = Expression.and(Expression.equals(ConversationEntries.ACCOUNT_ID, accountId), + Expression.equals(ConversationEntries.CONVERSATION_ID, conversationId)); final Cursor c = cr.query(ConversationEntries.CONTENT_URI, null, where.getSQL(), null, null); try { if (c.moveToFirst()) return ParcelableUser.fromDirectMessageConversationEntry(c); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/content/DatabaseUpgradeHelper.java b/twidere/src/main/java/org/mariotaku/twidere/util/content/DatabaseUpgradeHelper.java index 3f0e505f7..3e768779e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/content/DatabaseUpgradeHelper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/content/DatabaseUpgradeHelper.java @@ -19,23 +19,17 @@ package org.mariotaku.twidere.util.content; -import static org.mariotaku.querybuilder.SQLQueryBuilder.alterTable; -import static org.mariotaku.querybuilder.SQLQueryBuilder.createTable; -import static org.mariotaku.querybuilder.SQLQueryBuilder.dropTable; -import static org.mariotaku.querybuilder.SQLQueryBuilder.insertInto; -import static org.mariotaku.querybuilder.SQLQueryBuilder.select; - import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.text.TextUtils; import org.mariotaku.querybuilder.Columns; import org.mariotaku.querybuilder.Columns.Column; +import org.mariotaku.querybuilder.Expression; import org.mariotaku.querybuilder.NewColumn; +import org.mariotaku.querybuilder.OnConflict; import org.mariotaku.querybuilder.Tables; -import org.mariotaku.querybuilder.Where; -import org.mariotaku.querybuilder.query.SQLInsertIntoQuery; -import org.mariotaku.querybuilder.query.SQLInsertIntoQuery.OnConflict; +import org.mariotaku.querybuilder.query.SQLInsertQuery; import org.mariotaku.querybuilder.query.SQLSelectQuery; import org.mariotaku.twidere.util.ArrayUtils; @@ -46,145 +40,151 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import static org.mariotaku.querybuilder.SQLQueryBuilder.alterTable; +import static org.mariotaku.querybuilder.SQLQueryBuilder.createTable; +import static org.mariotaku.querybuilder.SQLQueryBuilder.dropTable; +import static org.mariotaku.querybuilder.SQLQueryBuilder.insertInto; +import static org.mariotaku.querybuilder.SQLQueryBuilder.select; + public final class DatabaseUpgradeHelper { - public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, - final String[] newColTypes, final boolean dropDirectly, final boolean strictMode, - final Map colAliases) { - safeUpgrade(db, table, newColNames, newColTypes, dropDirectly, strictMode, colAliases, OnConflict.REPLACE); - } + public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, + final String[] newColTypes, final boolean dropDirectly, final boolean strictMode, + final Map colAliases) { + safeUpgrade(db, table, newColNames, newColTypes, dropDirectly, strictMode, colAliases, OnConflict.REPLACE); + } - public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, - final String[] newColTypes, final boolean dropDirectly, final boolean strictMode, - final Map colAliases, final OnConflict onConflict) { + public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, + final String[] newColTypes, final boolean dropDirectly, final boolean strictMode, + final Map colAliases, final OnConflict onConflict) { - if (newColNames == null || newColTypes == null || newColNames.length != newColTypes.length) - throw new IllegalArgumentException("Invalid parameters for upgrading table " + table - + ", length of columns and types not match."); + if (newColNames == null || newColTypes == null || newColNames.length != newColTypes.length) + throw new IllegalArgumentException("Invalid parameters for upgrading table " + table + + ", length of columns and types not match."); - // First, create the table if not exists. - final NewColumn[] newCols = NewColumn.createNewColumns(newColNames, newColTypes); - final String createQuery = createTable(true, table).columns(newCols).buildSQL(); - db.execSQL(createQuery); + // First, create the table if not exists. + final NewColumn[] newCols = NewColumn.createNewColumns(newColNames, newColTypes); + final String createQuery = createTable(true, table).columns(newCols).buildSQL(); + db.execSQL(createQuery); - // We need to get all data from old table. - final String[] oldCols = getColumnNames(db, table); - if (strictMode) { - final String oldCreate = getCreateSQL(db, table); - final Map map = getTypeMapByCreateQuery(oldCreate); - boolean differenct = false; - for (final NewColumn newCol : newCols) { - if (!newCol.getType().equalsIgnoreCase(map.get(newCol.getName()))) { - differenct = true; - } - } - if (!differenct) return; - } else if (oldCols == null || ArrayUtils.contentMatch(newColNames, oldCols)) return; - if (dropDirectly) { - db.beginTransaction(); - db.execSQL(dropTable(true, table).getSQL()); - db.execSQL(createQuery); - db.setTransactionSuccessful(); - db.endTransaction(); - return; - } - final String tempTable = String.format(Locale.US, "temp_%s_%d", table, System.currentTimeMillis()); - db.beginTransaction(); - db.execSQL(alterTable(table).renameTo(tempTable).buildSQL()); - db.execSQL(createQuery); - final String[] notNullCols = getNotNullColumns(newCols); - final String insertQuery = createInsertDataQuery(table, tempTable, newColNames, oldCols, colAliases, - notNullCols, onConflict); - if (insertQuery != null) { - db.execSQL(insertQuery); - } - db.execSQL(dropTable(true, tempTable).getSQL()); - db.setTransactionSuccessful(); - db.endTransaction(); - } + // We need to get all data from old table. + final String[] oldCols = getColumnNames(db, table); + if (strictMode) { + final String oldCreate = getCreateSQL(db, table); + final Map map = getTypeMapByCreateQuery(oldCreate); + boolean differenct = false; + for (final NewColumn newCol : newCols) { + if (!newCol.getType().equalsIgnoreCase(map.get(newCol.getName()))) { + differenct = true; + } + } + if (!differenct) return; + } else if (oldCols == null || ArrayUtils.contentMatch(newColNames, oldCols)) return; + if (dropDirectly) { + db.beginTransaction(); + db.execSQL(dropTable(true, table).getSQL()); + db.execSQL(createQuery); + db.setTransactionSuccessful(); + db.endTransaction(); + return; + } + final String tempTable = String.format(Locale.US, "temp_%s_%d", table, System.currentTimeMillis()); + db.beginTransaction(); + db.execSQL(alterTable(table).renameTo(tempTable).buildSQL()); + db.execSQL(createQuery); + final String[] notNullCols = getNotNullColumns(newCols); + final String insertQuery = createInsertDataQuery(table, tempTable, newColNames, oldCols, colAliases, + notNullCols, onConflict); + if (insertQuery != null) { + db.execSQL(insertQuery); + } + db.execSQL(dropTable(true, tempTable).getSQL()); + db.setTransactionSuccessful(); + db.endTransaction(); + } - public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, - final String[] newColTypes, final boolean dropDirectly, final Map colAliases) { - safeUpgrade(db, table, newColNames, newColTypes, dropDirectly, true, colAliases, OnConflict.REPLACE); - } + public static void safeUpgrade(final SQLiteDatabase db, final String table, final String[] newColNames, + final String[] newColTypes, final boolean dropDirectly, final Map colAliases) { + safeUpgrade(db, table, newColNames, newColTypes, dropDirectly, true, colAliases, OnConflict.REPLACE); + } - private static String createInsertDataQuery(final String table, final String tempTable, final String[] newCols, - final String[] oldCols, final Map colAliases, final String[] notNullCols, - final OnConflict onConflict) { - final SQLInsertIntoQuery.Builder qb = insertInto(onConflict, table); - final List newInsertColsList = new ArrayList(); - for (final String newCol : newCols) { - final String oldAliasedCol = colAliases != null ? colAliases.get(newCol) : null; - if (ArrayUtils.contains(oldCols, newCol) || oldAliasedCol != null - && ArrayUtils.contains(oldCols, oldAliasedCol)) { - newInsertColsList.add(newCol); - } - } - final String[] newInsertCols = newInsertColsList.toArray(new String[newInsertColsList.size()]); - if (!ArrayUtils.contains(newInsertCols, notNullCols)) return null; - qb.columns(newInsertCols); - final Columns.Column[] oldDataCols = new Columns.Column[newInsertCols.length]; - for (int i = 0, j = oldDataCols.length; i < j; i++) { - final String newCol = newInsertCols[i]; - final String oldAliasedCol = colAliases != null ? colAliases.get(newCol) : null; - if (oldAliasedCol != null && ArrayUtils.contains(oldCols, oldAliasedCol)) { - oldDataCols[i] = new Columns.Column(oldAliasedCol, newCol); - } else { - oldDataCols[i] = new Columns.Column(newCol); - } - } - final SQLSelectQuery.Builder selectOldBuilder = select(new Columns(oldDataCols)); - selectOldBuilder.from(new Tables(tempTable)); - qb.select(selectOldBuilder.build()); - return qb.buildSQL(); - } + private static String createInsertDataQuery(final String table, final String tempTable, final String[] newCols, + final String[] oldCols, final Map colAliases, final String[] notNullCols, + final OnConflict onConflict) { + final SQLInsertQuery.Builder qb = insertInto(onConflict, table); + final List newInsertColsList = new ArrayList(); + for (final String newCol : newCols) { + final String oldAliasedCol = colAliases != null ? colAliases.get(newCol) : null; + if (ArrayUtils.contains(oldCols, newCol) || oldAliasedCol != null + && ArrayUtils.contains(oldCols, oldAliasedCol)) { + newInsertColsList.add(newCol); + } + } + final String[] newInsertCols = newInsertColsList.toArray(new String[newInsertColsList.size()]); + if (!ArrayUtils.contains(newInsertCols, notNullCols)) return null; + qb.columns(newInsertCols); + final Columns.Column[] oldDataCols = new Columns.Column[newInsertCols.length]; + for (int i = 0, j = oldDataCols.length; i < j; i++) { + final String newCol = newInsertCols[i]; + final String oldAliasedCol = colAliases != null ? colAliases.get(newCol) : null; + if (oldAliasedCol != null && ArrayUtils.contains(oldCols, oldAliasedCol)) { + oldDataCols[i] = new Columns.Column(oldAliasedCol, newCol); + } else { + oldDataCols[i] = new Columns.Column(newCol); + } + } + final SQLSelectQuery.Builder selectOldBuilder = select(new Columns(oldDataCols)); + selectOldBuilder.from(new Tables(tempTable)); + qb.select(selectOldBuilder.build()); + return qb.buildSQL(); + } - private static String[] getColumnNames(final SQLiteDatabase db, final String table) { - final Cursor cur = db.query(table, null, null, null, null, null, null, "1"); - if (cur == null) return null; - try { - return cur.getColumnNames(); - } finally { - cur.close(); - } - } + private static String[] getColumnNames(final SQLiteDatabase db, final String table) { + final Cursor cur = db.query(table, null, null, null, null, null, null, "1"); + if (cur == null) return null; + try { + return cur.getColumnNames(); + } finally { + cur.close(); + } + } - private static String getCreateSQL(final SQLiteDatabase db, final String table) { - final SQLSelectQuery.Builder qb = select(new Column("sql")); - qb.from(new Tables("sqlite_master")); - qb.where(new Where("type = ? AND name = ?")); - final Cursor c = db.rawQuery(qb.buildSQL(), new String[] { "table", table }); - if (c == null) return null; - try { - if (c.moveToFirst()) return c.getString(0); - return null; - } finally { - c.close(); - } - } + private static String getCreateSQL(final SQLiteDatabase db, final String table) { + final SQLSelectQuery.Builder qb = select(new Column("sql")); + qb.from(new Tables("sqlite_master")); + qb.where(new Expression("type = ? AND name = ?")); + final Cursor c = db.rawQuery(qb.buildSQL(), new String[]{"table", table}); + if (c == null) return null; + try { + if (c.moveToFirst()) return c.getString(0); + return null; + } finally { + c.close(); + } + } - private static String[] getNotNullColumns(final NewColumn[] newCols) { - if (newCols == null) return null; - final String[] notNullCols = new String[newCols.length]; - int count = 0; - for (final NewColumn column : newCols) { - if (column.getType().endsWith(" NOT NULL")) { - notNullCols[count++] = column.getName(); - } - } - return ArrayUtils.subArray(notNullCols, 0, count); - } + private static String[] getNotNullColumns(final NewColumn[] newCols) { + if (newCols == null) return null; + final String[] notNullCols = new String[newCols.length]; + int count = 0; + for (final NewColumn column : newCols) { + if (column.getType().endsWith(" NOT NULL")) { + notNullCols[count++] = column.getName(); + } + } + return ArrayUtils.subArray(notNullCols, 0, count); + } - private static Map getTypeMapByCreateQuery(final String query) { - if (TextUtils.isEmpty(query)) return Collections.emptyMap(); - final int start = query.indexOf("("), end = query.lastIndexOf(")"); - if (start < 0 || end < 0) return Collections.emptyMap(); - final HashMap map = new HashMap(); - for (final String segment : query.substring(start + 1, end).split(",")) { - final String trimmed = segment.trim().replaceAll(" +", " "); - final int idx = trimmed.indexOf(" "); - map.put(trimmed.substring(0, idx), trimmed.substring(idx + 1, trimmed.length())); - } - return map; - } + private static Map getTypeMapByCreateQuery(final String query) { + if (TextUtils.isEmpty(query)) return Collections.emptyMap(); + final int start = query.indexOf("("), end = query.lastIndexOf(")"); + if (start < 0 || end < 0) return Collections.emptyMap(); + final HashMap map = new HashMap(); + for (final String segment : query.substring(start + 1, end).split(",")) { + final String trimmed = segment.trim().replaceAll(" +", " "); + final int idx = trimmed.indexOf(" "); + map.put(trimmed.substring(0, idx), trimmed.substring(idx + 1, trimmed.length())); + } + return map; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/imageloader/TwidereImageDownloader.java b/twidere/src/main/java/org/mariotaku/twidere/util/imageloader/TwidereImageDownloader.java index 9f2b817e5..7979711ab 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/imageloader/TwidereImageDownloader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/imageloader/TwidereImageDownloader.java @@ -35,8 +35,8 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; -import org.mariotaku.twidere.model.Account; -import org.mariotaku.twidere.model.Account.AccountWithCredentials; +import org.mariotaku.twidere.model.ParcelableAccount; +import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.util.MediaPreviewUtils; import org.mariotaku.twidere.util.Utils; @@ -125,10 +125,10 @@ public class TwidereImageDownloader extends BaseImageDownloader implements Const throws IOException, TwitterException { final Uri uri = Uri.parse(uriString); final Authorization auth; - final AccountWithCredentials account; + final ParcelableAccountWithCredentials account; if (isTwitterAuthRequired(uri) && extras instanceof AccountExtra) { final AccountExtra accountExtra = (AccountExtra) extras; - account = Account.getAccountWithCredentials(mContext, accountExtra.account_id); + account = ParcelableAccount.getAccountWithCredentials(mContext, accountExtra.account_id); auth = getTwitterAuthorization(mContext, accountExtra.account_id); } else { account = null; diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/BottomDividerFrameLayout.java b/twidere/src/main/java/org/mariotaku/twidere/view/BottomDividerFrameLayout.java new file mode 100644 index 000000000..b518eed5f --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/view/BottomDividerFrameLayout.java @@ -0,0 +1,71 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +/** + * Created by mariotaku on 14/12/4. + */ +public class BottomDividerFrameLayout extends FrameLayout { + + private final Drawable mDividerDrawable; + + public BottomDividerFrameLayout(Context context) { + this(context, null); + } + + public BottomDividerFrameLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BottomDividerFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setWillNotDraw(false); + TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.divider}); + mDividerDrawable = a.getDrawable(0); + a.recycle(); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + final Drawable divider = mDividerDrawable; + if (divider != null) { + final int drawableLeft = 0, drawableRight = drawableLeft + getMeasuredWidth(); + final int drawableBottom = getMeasuredHeight(), drawableTop = drawableBottom - divider.getIntrinsicHeight(); + divider.setBounds(drawableLeft, drawableTop, drawableRight, drawableBottom); + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + final Drawable divider = mDividerDrawable; + if (divider != null) { + divider.draw(canvas); + } + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/RefreshNowStaggeredGridView.java b/twidere/src/main/java/org/mariotaku/twidere/view/RefreshNowStaggeredGridView.java deleted file mode 100644 index decbc51b5..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/RefreshNowStaggeredGridView.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.mariotaku.twidere.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -import com.etsy.android.grid.StaggeredGridView; - -import org.mariotaku.refreshnow.widget.OnRefreshListener; -import org.mariotaku.refreshnow.widget.RefreshMode; -import org.mariotaku.refreshnow.widget.RefreshNowConfig; -import org.mariotaku.refreshnow.widget.iface.IRefreshNowView; - -public class RefreshNowStaggeredGridView extends StaggeredGridView implements IRefreshNowView { - - private final Helper mHelper; - - public RefreshNowStaggeredGridView(final Context context) { - this(context, null); - } - - public RefreshNowStaggeredGridView(final Context context, final AttributeSet attrs) { - this(context, attrs, 0); - } - - public RefreshNowStaggeredGridView(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); - mHelper = new Helper(this, context, attrs, defStyle); - } - - @Override - public RefreshMode getRefreshMode() { - return mHelper.getRefreshMode(); - } - - @Override - public boolean isRefreshing() { - return mHelper.isRefreshing(); - } - - @Override - public boolean onTouchEvent(final MotionEvent ev) { - return super.onTouchEvent(mHelper.processOnTouchEvent(ev)); - } - - @Override - public void setConfig(final RefreshNowConfig config) { - mHelper.setConfig(config); - } - - @Override - public void setFriction(final float friction) { - super.setFriction(friction); - mHelper.setFriction(friction); - } - - @Override - public void setOnRefreshListener(final OnRefreshListener listener) { - mHelper.setOnRefreshListener(listener); - } - - @Override - public void setRefreshComplete() { - mHelper.setRefreshComplete(); - } - - @Override - public void setRefreshIndicatorView(final View view) { - mHelper.setRefreshIndicatorView(view); - } - - @Override - public View getRefreshIndicatorView() { - return mHelper.getRefreshIndicatorView(); - } - - @Override - public void setRefreshing(final boolean refreshing) { - mHelper.setRefreshing(refreshing); - } - - @Override - public void setRefreshMode(final RefreshMode mode) { - mHelper.setRefreshMode(mode); - } - - @Override - protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) { - super.onScrollChanged(l, t, oldl, oldt); - mHelper.dispatchOnScrollChanged(l, t, oldl, oldt); - } - - @Override - protected boolean overScrollBy(final int deltaX, final int deltaY, final int scrollX, final int scrollY, - final int scrollRangeX, final int scrollRangeY, final int maxOverScrollX, final int maxOverScrollY, - final boolean isTouchEvent) { - return true; - } - -} \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/DirectMessageEntryViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/DirectMessageEntryViewHolder.java index d4aea9ffe..1b2bd2f96 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/DirectMessageEntryViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/DirectMessageEntryViewHolder.java @@ -28,60 +28,52 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.view.ShortTimeView; -import org.mariotaku.twidere.view.iface.ICardItemView; -public class DirectMessageEntryViewHolder extends CardViewHolder { +public class DirectMessageEntryViewHolder extends ViewHolder { - public final ImageView profile_image; - public final TextView name, screen_name, text; - public final ShortTimeView time; - public final ICardItemView content; - private float text_size; - private boolean account_color_enabled; - private final boolean is_rtl; + public final ImageView profile_image; + public final TextView name, text; + public final ShortTimeView time; + private float text_size; + private boolean account_color_enabled; + private final boolean is_rtl; - public DirectMessageEntryViewHolder(final View view) { - super(view); - final Context context = view.getContext(); - content = (ICardItemView) findViewById(R.id.content); - profile_image = (ImageView) findViewById(R.id.profile_image); - name = (TextView) findViewById(R.id.name); - screen_name = (TextView) findViewById(R.id.screen_name); - text = (TextView) findViewById(R.id.text); - time = (ShortTimeView) findViewById(R.id.time); - is_rtl = Utils.isRTL(context); - } + public DirectMessageEntryViewHolder(final View view) { + super(view); + final Context context = view.getContext(); + profile_image = (ImageView) findViewById(R.id.profile_image); + name = (TextView) findViewById(R.id.name); + text = (TextView) findViewById(R.id.text); + time = (ShortTimeView) findViewById(R.id.time); + is_rtl = Utils.isRTL(context); + } - public void setAccountColor(final int color) { - content.drawEnd(account_color_enabled ? color : Color.TRANSPARENT); - } + public void setAccountColor(final int color) { +// content.drawEnd(account_color_enabled ? color : Color.TRANSPARENT); + } - public void setAccountColorEnabled(final boolean enabled) { - if (account_color_enabled == enabled) return; - account_color_enabled = enabled; - if (!account_color_enabled) { - content.drawEnd(Color.TRANSPARENT); - } - } + public void setAccountColorEnabled(final boolean enabled) { + if (account_color_enabled == enabled) return; + account_color_enabled = enabled; + if (!account_color_enabled) { +// content.drawEnd(Color.TRANSPARENT); + } + } - public void setIsOutgoing(final boolean is_outgoing) { - if (is_rtl) { - time.setCompoundDrawablesWithIntrinsicBounds(is_outgoing ? R.drawable.ic_indicator_sent : 0, 0, 0, 0); - } else { - time.setCompoundDrawablesWithIntrinsicBounds(0, 0, is_outgoing ? R.drawable.ic_indicator_sent : 0, 0); - } - } + public void setIsOutgoing(final boolean is_outgoing) { + if (is_rtl) { + time.setCompoundDrawablesWithIntrinsicBounds(is_outgoing ? R.drawable.ic_indicator_sent : 0, 0, 0, 0); + } else { + time.setCompoundDrawablesWithIntrinsicBounds(0, 0, is_outgoing ? R.drawable.ic_indicator_sent : 0, 0); + } + } - public void setTextSize(final float text_size) { - if (this.text_size == text_size) return; - this.text_size = text_size; - text.setTextSize(text_size); - name.setTextSize(text_size); - screen_name.setTextSize(text_size * 0.75f); - time.setTextSize(text_size * 0.65f); - } + public void setTextSize(final float text_size) { + if (this.text_size == text_size) return; + this.text_size = text_size; + } - public void setUserColor(final int color) { - content.drawStart(color); - } + public void setUserColor(final int color) { +// content.drawStart(color); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java index 8653b9151..54d89c1a9 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java @@ -1,7 +1,6 @@ package org.mariotaku.twidere.view.holder; import android.content.Context; -import android.content.Intent; import android.database.Cursor; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; @@ -12,7 +11,6 @@ import android.widget.TextView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IStatusesAdapter; -import org.mariotaku.twidere.constant.IntentConstants; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices; @@ -29,9 +27,9 @@ import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes; /** * Created by mariotaku on 14/11/19. */ -public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClickListener { +public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClickListener { - private final IStatusesAdapter adapter; + private final IStatusesAdapter adapter; private final ImageView retweetProfileImageView; private final CircularImageView profileImageView; @@ -44,7 +42,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements O private final View mediaPreviewContainer; private final TextView replyCountView, retweetCountView, favoriteCountView; - public StatusViewHolder(IStatusesAdapter adapter, View itemView) { + public StatusViewHolder(IStatusesAdapter adapter, View itemView) { super(itemView); this.adapter = adapter; itemView.findViewById(R.id.item_content).setOnClickListener(this); @@ -70,7 +68,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements O itemView.setOnClickListener(this); profileImageView.setOnClickListener(this); mediaPreviewContainer.setOnClickListener(this); - retweetCountView.setOnClickListener(this); + replyCountView.setOnClickListener(this); retweetCountView.setOnClickListener(this); favoriteCountView.setOnClickListener(this); } @@ -280,9 +278,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements O @Override public void onClick(View v) { - final Context context = itemView.getContext(); final int position = getPosition(); - final ParcelableStatus status = adapter.getStatus(position); switch (v.getId()) { case R.id.item_content: { adapter.onStatusClick(this, position); @@ -297,10 +293,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements O break; } case R.id.reply_count: { - final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY); - intent.setPackage(context.getPackageName()); - intent.putExtra(IntentConstants.EXTRA_STATUS, status); - context.startActivity(intent); + adapter.onItemActionClick(this, v.getId(), position); break; } } diff --git a/twidere/src/main/res/drawable-hdpi/ic_user_type_protected.png b/twidere/src/main/res/drawable-hdpi/ic_user_type_protected.png index afe19e747..e83a82f2a 100755 Binary files a/twidere/src/main/res/drawable-hdpi/ic_user_type_protected.png and b/twidere/src/main/res/drawable-hdpi/ic_user_type_protected.png differ diff --git a/twidere/src/main/res/drawable-hdpi/ic_user_type_verified.png b/twidere/src/main/res/drawable-hdpi/ic_user_type_verified.png index 2ec613d1e..2537b04b3 100755 Binary files a/twidere/src/main/res/drawable-hdpi/ic_user_type_verified.png and b/twidere/src/main/res/drawable-hdpi/ic_user_type_verified.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_user_type_protected.png b/twidere/src/main/res/drawable-mdpi/ic_user_type_protected.png index 5a956191d..d3854790a 100755 Binary files a/twidere/src/main/res/drawable-mdpi/ic_user_type_protected.png and b/twidere/src/main/res/drawable-mdpi/ic_user_type_protected.png differ diff --git a/twidere/src/main/res/drawable-mdpi/ic_user_type_verified.png b/twidere/src/main/res/drawable-mdpi/ic_user_type_verified.png index ed5042113..c9f12f463 100755 Binary files a/twidere/src/main/res/drawable-mdpi/ic_user_type_verified.png and b/twidere/src/main/res/drawable-mdpi/ic_user_type_verified.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_user_type_protected.png b/twidere/src/main/res/drawable-xhdpi/ic_user_type_protected.png index 1da5ef88c..1b0d6fe52 100755 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_user_type_protected.png and b/twidere/src/main/res/drawable-xhdpi/ic_user_type_protected.png differ diff --git a/twidere/src/main/res/drawable-xhdpi/ic_user_type_verified.png b/twidere/src/main/res/drawable-xhdpi/ic_user_type_verified.png index 6533cdd3d..3933b5479 100755 Binary files a/twidere/src/main/res/drawable-xhdpi/ic_user_type_verified.png and b/twidere/src/main/res/drawable-xhdpi/ic_user_type_verified.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_user_type_protected.png b/twidere/src/main/res/drawable-xxhdpi/ic_user_type_protected.png index 362c91de6..e6f3eb2ef 100755 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_user_type_protected.png and b/twidere/src/main/res/drawable-xxhdpi/ic_user_type_protected.png differ diff --git a/twidere/src/main/res/drawable-xxhdpi/ic_user_type_verified.png b/twidere/src/main/res/drawable-xxhdpi/ic_user_type_verified.png index cf245878d..31f10aaff 100755 Binary files a/twidere/src/main/res/drawable-xxhdpi/ic_user_type_verified.png and b/twidere/src/main/res/drawable-xxhdpi/ic_user_type_verified.png differ diff --git a/twidere/src/main/res/layout-v21/list_item_preference_header_category.xml b/twidere/src/main/res/layout-v21/list_item_preference_header_category.xml new file mode 100644 index 000000000..6162f21b4 --- /dev/null +++ b/twidere/src/main/res/layout-v21/list_item_preference_header_category.xml @@ -0,0 +1,43 @@ + + + + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout-v21/list_item_preference_header_item.xml b/twidere/src/main/res/layout-v21/list_item_preference_header_item.xml new file mode 100644 index 000000000..004a74f9f --- /dev/null +++ b/twidere/src/main/res/layout-v21/list_item_preference_header_item.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twidere/src/main/res/layout-v21/list_item_preference_header_space.xml b/twidere/src/main/res/layout-v21/list_item_preference_header_space.xml new file mode 100644 index 000000000..ae8159d8d --- /dev/null +++ b/twidere/src/main/res/layout-v21/list_item_preference_header_space.xml @@ -0,0 +1,23 @@ + + + + diff --git a/twidere/src/main/res/layout/activity_filters.xml b/twidere/src/main/res/layout/activity_filters.xml index 14c3fd6a1..7e14b0f7b 100644 --- a/twidere/src/main/res/layout/activity_filters.xml +++ b/twidere/src/main/res/layout/activity_filters.xml @@ -4,6 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:fitsSystemWindows="true" tools:context=".activity.FiltersActivity"> - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/layout/card_item_message_entry_compact.xml b/twidere/src/main/res/layout/card_item_message_entry_compact.xml deleted file mode 100644 index 3edba8c8c..000000000 --- a/twidere/src/main/res/layout/card_item_message_entry_compact.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/layout/fragment_content_pages.xml b/twidere/src/main/res/layout/fragment_content_pages.xml index 96b870b8c..c45fa89bc 100644 --- a/twidere/src/main/res/layout/fragment_content_pages.xml +++ b/twidere/src/main/res/layout/fragment_content_pages.xml @@ -30,7 +30,9 @@ android:layout_width="match_parent" android:layout_height="@dimen/element_size_normal" android:textColor="?android:textColorSecondary" - app:pstsTabBackground="?android:selectableItemBackground"/> + app:pstsTabBackground="?android:selectableItemBackground" + app:pstsShouldExpand="true" + app:pstsTabPaddingLeftRight="@dimen/element_spacing_large"/> + android:layout_height="wrap_content" + android:foreground="?android:selectableItemBackground">