added border to user type icon
redesigning settings screen removed staggered grid support, will use new implementation soon redesigning direct message entries list
This commit is contained in:
parent
4cc47a3af1
commit
00c0740d38
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 29 KiB |
|
@ -83,7 +83,6 @@ dependencies {
|
|||
compile 'com.android.support:cardview-v7:21.0.2'
|
||||
compile 'com.android.support: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'
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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 + ".*" : "*";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Expression implements SQLLang {
|
||||
private final String expr;
|
||||
|
||||
public Expression(final String expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public Expression(SQLLang lang) {
|
||||
this(lang.getSQL());
|
||||
}
|
||||
|
||||
public static Expression and(final Expression... expressions) {
|
||||
return new Expression(toExpr(expressions, "AND"));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final Column r) {
|
||||
return new Expression(String.format(Locale.US, "%s = %s", l.getSQL(), r.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final long r) {
|
||||
return new Expression(String.format(Locale.US, "%s = %d", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final String r) {
|
||||
return new Expression(String.format(Locale.US, "%s = '%s'", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Expression equals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.US, "%s = %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression in(final Column column, final Selectable in) {
|
||||
return new Expression(String.format("%s IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression notEquals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.US, "%s != %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression notEquals(final String l, final String r) {
|
||||
return new Expression(String.format("%s != %s", l, r));
|
||||
}
|
||||
|
||||
public static Expression notIn(final Column column, final Selectable in) {
|
||||
return new Expression(String.format("%s NOT IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression notNull(final Column column) {
|
||||
return new Expression(String.format("%s NOT NULL", column.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression or(final Expression... expressions) {
|
||||
return new Expression(toExpr(expressions, "OR"));
|
||||
}
|
||||
|
||||
private static String toExpr(final Expression[] array, final String token) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append('(');
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(String.format(" %s ", token));
|
||||
}
|
||||
builder.append(array[i].getSQL());
|
||||
}
|
||||
builder.append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static Expression equalsArgs(String l) {
|
||||
return new Expression(String.format(Locale.US, "%s = ?", l));
|
||||
}
|
||||
|
||||
public static Expression isNull(Column column) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s IS NULL", column.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression greaterThan(Column column1, Column column2) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s > %s", column1.getSQL(), column2.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression like(final Column l, final String r) {
|
||||
return new Expression(String.format(Locale.US, "%s LIKE '%s'", l.getSQL(), r));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return expr;
|
||||
}
|
||||
}
|
|
@ -2,36 +2,37 @@ package org.mariotaku.querybuilder;
|
|||
|
||||
public class NewColumn implements SQLLang {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-7.
|
||||
*/
|
||||
public enum OnConflict {
|
||||
ROLLBACK("ROLLBACK"), ABORT("ABORT"), REPLACE("REPLACE"), FAIL("FAIL"), IGNORE("IGNORE");
|
||||
private final String action;
|
||||
|
||||
OnConflict(final String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
*
|
||||
* 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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-6.
|
||||
*/
|
||||
public interface SQLQuery extends SQLLang {
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
*
|
||||
* 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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.mariotaku.querybuilder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-7.
|
||||
*/
|
||||
public class SetValue implements SQLLang {
|
||||
|
||||
private final Columns.Column column;
|
||||
private final Expression expression;
|
||||
|
||||
public SetValue(Columns.Column column, Expression expression) {
|
||||
this.column = column;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return String.format(Locale.ROOT, "%s = %s", column.getSQL(), expression.getSQL());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class Table implements Selectable {
|
||||
|
||||
public static final Table NEW = new Table("NEW");
|
||||
|
||||
private final String table;
|
||||
|
||||
public Table(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
*
|
||||
* 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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Where implements SQLLang {
|
||||
private final String expr;
|
||||
|
||||
public Where(final String expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return expr;
|
||||
}
|
||||
|
||||
public static Where and(final Where... expressions) {
|
||||
return new Where(toExpr(expressions, "AND"));
|
||||
}
|
||||
|
||||
public static Where equals(final Column l, final Column r) {
|
||||
return new Where(String.format(Locale.ROOT, "%s = %s", l.getSQL(), r.getSQL()));
|
||||
}
|
||||
|
||||
public static Where equals(final Column l, final long r) {
|
||||
return new Where(String.format(Locale.ROOT, "%s = %d", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Where equals(final Column l, final String r) {
|
||||
return new Where(String.format(Locale.ROOT, "%s = '%s'", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Where equals(final String l, final long r) {
|
||||
return new Where(String.format(Locale.ROOT, "%s = %d", l, r));
|
||||
}
|
||||
|
||||
public static Where in(final Column column, final Selectable in) {
|
||||
return new Where(String.format("%s IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Where notEquals(final String l, final long r) {
|
||||
return new Where(String.format(Locale.ROOT, "%s != %d", l, r));
|
||||
}
|
||||
|
||||
public static Where notEquals(final String l, final String r) {
|
||||
return new Where(String.format("%s != %s", l, r));
|
||||
}
|
||||
|
||||
public static Where notIn(final Column column, final Selectable in) {
|
||||
return new Where(String.format("%s NOT IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Where notNull(final Column column) {
|
||||
return new Where(String.format("%s NOT NULL", column.getSQL()));
|
||||
}
|
||||
|
||||
public static Where or(final Where... expressions) {
|
||||
return new Where(toExpr(expressions, "OR"));
|
||||
}
|
||||
|
||||
private static String toExpr(final Where[] array, final String token) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append('(');
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(String.format(" %s ", token));
|
||||
}
|
||||
builder.append(array[i].getSQL());
|
||||
}
|
||||
builder.append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -4,13 +4,13 @@ import org.mariotaku.querybuilder.SQLLang;
|
|||
|
||||
public interface IBuilder<T extends SQLLang> {
|
||||
|
||||
public 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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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<SQLAlterTableQuery> {
|
||||
public static final class Builder implements IBuilder<SQLAlterTableQuery> {
|
||||
|
||||
private boolean buildCalled;
|
||||
private final SQLAlterTableQuery query = new SQLAlterTableQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
private final SQLAlterTableQuery query = new SQLAlterTableQuery();
|
||||
public Builder addColumn(final NewColumn addColumn) {
|
||||
checkNotBuilt();
|
||||
query.setAddColumn(addColumn);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addColumn(final NewColumn addColumn) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<SQLCreateTableQuery> {
|
||||
public static final class Builder implements IBuilder<SQLCreateTableQuery> {
|
||||
|
||||
private final SQLCreateTableQuery query = new SQLCreateTableQuery();
|
||||
private final SQLCreateTableQuery query = new SQLCreateTableQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder as(final SQLSelectQuery selectStmt) {
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.SQLLang;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-6.
|
||||
*/
|
||||
public class SQLCreateTriggerQuery implements SQLQuery {
|
||||
|
||||
private boolean temporary;
|
||||
private boolean createIfNotExists;
|
||||
private boolean forEachRow;
|
||||
private String name;
|
||||
private Table on;
|
||||
private Type type;
|
||||
private Event event;
|
||||
private Columns updateOf;
|
||||
private SQLQuery[] actions;
|
||||
private Expression when;
|
||||
|
||||
void setActions(SQLQuery[] actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
void setForEachRow(boolean forEachRow) {
|
||||
this.forEachRow = forEachRow;
|
||||
}
|
||||
|
||||
void setOn(Table on) {
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
void setUpdateOf(Columns updateOf) {
|
||||
this.updateOf = updateOf;
|
||||
}
|
||||
|
||||
void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
void setEvent(Event event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
void setWhen(Expression when) {
|
||||
this.when = when;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (name == null) throw new NullPointerException("NAME must not be null!");
|
||||
if (event == null) throw new NullPointerException("EVENT must not be null!");
|
||||
if (on == null) throw new NullPointerException("ON must not be null!");
|
||||
if (actions == null) throw new NullPointerException("ACTIONS must not be null!");
|
||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||
if (temporary) {
|
||||
sb.append("TEMPORARY ");
|
||||
}
|
||||
sb.append("TRIGGER ");
|
||||
if (createIfNotExists) {
|
||||
sb.append("IF NOT EXISTS ");
|
||||
}
|
||||
sb.append(name);
|
||||
sb.append(' ');
|
||||
if (type != null) {
|
||||
sb.append(type.getSQL());
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(event.getSQL());
|
||||
sb.append(' ');
|
||||
if (event == Event.UPDATE) {
|
||||
sb.append(String.format(Locale.ROOT, "%s ", updateOf.getSQL()));
|
||||
}
|
||||
sb.append(String.format(Locale.ROOT, "ON %s ", on.getSQL()));
|
||||
if (forEachRow) {
|
||||
sb.append("FOR EACH ROW ");
|
||||
}
|
||||
if (when != null) {
|
||||
sb.append(String.format(Locale.ROOT, "WHEN %s ", when.getSQL()));
|
||||
}
|
||||
sb.append(String.format(Locale.ROOT, "BEGIN %s; END", Utils.toString(actions, ';', true)));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||
this.createIfNotExists = createIfNotExists;
|
||||
}
|
||||
|
||||
void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
void setTemporary(final boolean temporary) {
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public static enum Type implements SQLLang {
|
||||
BEFORE("BEFORE"), AFTER("AFTER"), INSTEAD_OF("INSTEAD OF");
|
||||
private final String lang;
|
||||
|
||||
Type(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Event implements SQLLang {
|
||||
INSERT("INSERT"), DELETE("DELETE"), UPDATE("UPDATE");
|
||||
private final String lang;
|
||||
|
||||
Event(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder implements IBuilder<SQLCreateTriggerQuery> {
|
||||
|
||||
private final SQLCreateTriggerQuery query = new SQLCreateTriggerQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder forEachRow(final boolean forEachRow) {
|
||||
checkNotBuilt();
|
||||
query.setForEachRow(forEachRow);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder on(final Table on) {
|
||||
checkNotBuilt();
|
||||
query.setOn(on);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder event(Event event) {
|
||||
checkNotBuilt();
|
||||
query.setEvent(event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder type(Type type) {
|
||||
checkNotBuilt();
|
||||
query.setType(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder updateOf(Columns updateOf) {
|
||||
checkNotBuilt();
|
||||
query.setUpdateOf(updateOf);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder actions(SQLQuery... actions) {
|
||||
checkNotBuilt();
|
||||
query.setActions(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder when(Expression when) {
|
||||
checkNotBuilt();
|
||||
query.setWhen(when);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLCreateTriggerQuery build() {
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public Builder createTrigger(boolean temporary, boolean createIfNotExists, String name) {
|
||||
checkNotBuilt();
|
||||
query.setTemporary(temporary);
|
||||
query.setCreateIfNotExists(createIfNotExists);
|
||||
query.setName(name);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +1,90 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
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<SQLCreateViewQuery> {
|
||||
public static final class Builder implements IBuilder<SQLCreateViewQuery> {
|
||||
|
||||
private boolean buildCalled;
|
||||
private final SQLCreateViewQuery query = new SQLCreateViewQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
private final SQLCreateViewQuery query = new SQLCreateViewQuery();
|
||||
public Builder as(final SQLSelectQuery selectStmt) {
|
||||
checkNotBuilt();
|
||||
query.setAs(selectStmt);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder as(final SQLSelectQuery selectStmt) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<SQLDeleteQuery> {
|
||||
private boolean buildCalled;
|
||||
private final SQLDeleteQuery query = new SQLDeleteQuery();
|
||||
public static final class Builder implements IBuilder<SQLDeleteQuery> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
public class SQLDropTriggerQuery extends SQLDropQuery {
|
||||
|
||||
public SQLDropTriggerQuery(final boolean dropIfExists, final String table) {
|
||||
super(dropIfExists, "TRIGGER", table);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +1,9 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.SQLLang;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
public class SQLInsertIntoQuery implements SQLLang {
|
||||
|
||||
private OnConflict onConflict;
|
||||
private String table;
|
||||
private String[] columns;
|
||||
private SQLSelectQuery select;
|
||||
|
||||
SQLInsertIntoQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("INSERT ");
|
||||
if (onConflict != null) {
|
||||
sb.append(String.format("OR %s ", onConflict.getAction()));
|
||||
}
|
||||
sb.append(String.format("INTO %s ", table));
|
||||
sb.append(String.format("(%s) ", Utils.toString(columns, ',', false)));
|
||||
sb.append(String.format("%s ", select.getSQL()));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setColumns(final String[] columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
void setOnConflict(final OnConflict onConflict) {
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
void setSelect(final SQLSelectQuery select) {
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLInsertIntoQuery> {
|
||||
|
||||
private final SQLInsertIntoQuery query = new SQLInsertIntoQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLInsertIntoQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder columns(final String[] columns) {
|
||||
checkNotBuilt();
|
||||
query.setColumns(columns);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final OnConflict onConflict, final String table) {
|
||||
checkNotBuilt();
|
||||
query.setOnConflict(onConflict);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final String table) {
|
||||
return insertInto(null, table);
|
||||
}
|
||||
|
||||
public Builder select(final SQLSelectQuery select) {
|
||||
checkNotBuilt();
|
||||
query.setSelect(select);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static enum OnConflict {
|
||||
ROLLBACK("ROLLBACK"), ABORT("ABORT"), REPLACE("REPLACE"), FAIL("FAIL"), IGNORE("IGNORE");
|
||||
private final String action;
|
||||
|
||||
private OnConflict(final String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
public class SQLInsertQuery implements SQLQuery {
|
||||
|
||||
private OnConflict onConflict;
|
||||
private String table;
|
||||
private String[] columns;
|
||||
private SQLSelectQuery select;
|
||||
|
||||
SQLInsertQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("INSERT ");
|
||||
if (onConflict != null) {
|
||||
sb.append(String.format("OR %s ", onConflict.getAction()));
|
||||
}
|
||||
sb.append(String.format("INTO %s ", table));
|
||||
sb.append(String.format("(%s) ", Utils.toString(columns, ',', false)));
|
||||
sb.append(String.format("%s ", select.getSQL()));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setColumns(final String[] columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
void setOnConflict(final OnConflict onConflict) {
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
void setSelect(final SQLSelectQuery select) {
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLInsertQuery> {
|
||||
|
||||
private final SQLInsertQuery query = new SQLInsertQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLInsertQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder columns(final String[] columns) {
|
||||
checkNotBuilt();
|
||||
query.setColumns(columns);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final OnConflict onConflict, final String table) {
|
||||
checkNotBuilt();
|
||||
query.setOnConflict(onConflict);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final String table) {
|
||||
return insertInto(null, table);
|
||||
}
|
||||
|
||||
public Builder select(final SQLSelectQuery select) {
|
||||
checkNotBuilt();
|
||||
query.setSelect(select);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
*
|
||||
* 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 <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
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<InternalQuery> internalQueries = new ArrayList<InternalQuery>();
|
||||
private final List<InternalQuery> internalQueries = new ArrayList<InternalQuery>();
|
||||
|
||||
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<SQLSelectQuery> {
|
||||
private boolean buildCalled;
|
||||
private final SQLSelectQuery query = new SQLSelectQuery();
|
||||
public static final class Builder implements IBuilder<SQLSelectQuery> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.SetValue;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class SQLUpdateQuery implements SQLQuery {
|
||||
|
||||
private OnConflict onConflict;
|
||||
private String table;
|
||||
private SetValue[] values;
|
||||
private Expression where;
|
||||
|
||||
SQLUpdateQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("UPDATE ");
|
||||
if (onConflict != null) {
|
||||
sb.append(String.format(Locale.ROOT, "OR %s ", onConflict.getAction()));
|
||||
}
|
||||
sb.append(String.format(Locale.ROOT, "%s ", table));
|
||||
sb.append(String.format(Locale.ROOT, "SET %s ", Utils.toString(values, ',', false)));
|
||||
if (where != null) {
|
||||
sb.append(String.format(Locale.ROOT, "WHERE %s ", where.getSQL()));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setWhere(final Expression where) {
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
void setValues(final SetValue[] columns) {
|
||||
this.values = columns;
|
||||
}
|
||||
|
||||
void setOnConflict(final OnConflict onConflict) {
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLUpdateQuery> {
|
||||
|
||||
private final SQLUpdateQuery query = new SQLUpdateQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLUpdateQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder set(final SetValue... values) {
|
||||
checkNotBuilt();
|
||||
query.setValues(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder where(final Expression where) {
|
||||
checkNotBuilt();
|
||||
query.setWhere(where);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder update(final OnConflict onConflict, final String table) {
|
||||
checkNotBuilt();
|
||||
query.setOnConflict(onConflict);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder update(final String table) {
|
||||
return update(null, table);
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -175,7 +175,7 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
|||
public static final int VIRTUAL_TABLE_ID_UNREAD_COUNTS_BY_TYPE = 109;
|
||||
|
||||
public static final int 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<Header> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Account> {
|
||||
private static class AccountSelectorAdapter extends BaseArrayAdapter<ParcelableAccount> {
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<SupportTabSpec> mCustomTabs = new ArrayList<SupportTabSpec>();
|
||||
|
||||
private final SparseArray<Fragment> mAttachedFragments = new SparseArray<Fragment>();
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<D> extends Adapter<ViewHolder> 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<D> extends Adapter<ViewHolder> 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<D> extends Adapter<ViewHolder> 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<D> extends Adapter<ViewHolder> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Account> {
|
||||
public class AccountsSpinnerAdapter extends ArrayAdapter<ParcelableAccount> {
|
||||
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final boolean mDisplayProfileImage;
|
||||
|
@ -48,7 +46,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<Account> {
|
|||
Context.MODE_PRIVATE).getBoolean(DirectMessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
}
|
||||
|
||||
public AccountsSpinnerAdapter(final Context context, final Collection<Account> accounts) {
|
||||
public AccountsSpinnerAdapter(final Context context, final Collection<ParcelableAccount> accounts) {
|
||||
this(context);
|
||||
addAll(accounts);
|
||||
}
|
||||
|
@ -67,7 +65,7 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<Account> {
|
|||
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);
|
||||
|
|
|
@ -73,11 +73,6 @@ public class CursorStatusesAdapter extends AbsStatusesAdapter<Cursor> {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getData() {
|
||||
return mCursor;
|
||||
|
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,6 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter<List<Parcelabl
|
|||
return getStatus(position).is_gap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||
holder.displayStatus(getStatus(position));
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -105,7 +106,12 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
||||
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(ViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -184,7 +190,7 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
public void onGapClick(ViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.Where;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
|
@ -169,7 +169,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
builder.append(" OR ");
|
||||
builder.append(CachedUsers.NAME + " LIKE ?||'%' ESCAPE '^'");
|
||||
builder.append(" OR ");
|
||||
builder.append(Where.in(new Column(CachedUsers.USER_ID),
|
||||
builder.append(Expression.in(new Column(CachedUsers.USER_ID),
|
||||
new RawItemArray(getMatchedNicknameIds(ParseUtils.parseString(constraint)))).getSQL());
|
||||
final String selection = constraint_escaped != null ? builder.toString() : null;
|
||||
final String[] selectionArgs = constraint_escaped != null ? new String[]{constraint_escaped,
|
||||
|
|
|
@ -24,6 +24,8 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
|
|||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public interface IItemMenuSupportedAdapter<VH extends ViewHolder> {
|
||||
void onItemMenuClick(VH holder, int position);
|
||||
public interface ICardSupportedAdapter {
|
||||
void onItemActionClick(ViewHolder holder, int id, int position);
|
||||
|
||||
void onItemMenuClick(ViewHolder holder, int position);
|
||||
}
|
|
@ -24,10 +24,10 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
|
|||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public interface IGapSupportedAdapter<VH extends ViewHolder> {
|
||||
public interface IGapSupportedAdapter {
|
||||
|
||||
boolean isGapItem(int position);
|
||||
|
||||
void onGapClick(VH holder, int position);
|
||||
void onGapClick(ViewHolder holder, int position);
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
|||
/**
|
||||
* Created by mariotaku on 14/11/18.
|
||||
*/
|
||||
public interface IStatusesAdapter<Data> extends IGapSupportedAdapter<StatusViewHolder>,
|
||||
IItemMenuSupportedAdapter<StatusViewHolder> {
|
||||
public interface IStatusesAdapter<Data> extends IGapSupportedAdapter, ICardSupportedAdapter {
|
||||
|
||||
ImageLoaderWrapper getImageLoader();
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ public interface IntentConstants {
|
|||
public static final String BROADCAST_FRIENDSHIP_DENIED = INTENT_PACKAGE_PREFIX + "FRIENDSHIP_DENIED";
|
||||
|
||||
public static final String BROADCAST_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";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Data> extends BaseSupportFragment
|
||||
implements LoaderCallbacks<Data>, OnRefreshListener, DrawerCallback {
|
||||
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment implements LoaderCallbacks<Data>,
|
||||
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<Data> mAdapter;
|
||||
private SimpleDrawerCallback mDrawerCallback;
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
if (isRefreshing()) return;
|
||||
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
||||
onLoadMoreStatuses();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean canScroll(float dy) {
|
||||
return mDrawerCallback.canScroll(dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTouch() {
|
||||
mDrawerCallback.cancelTouch();
|
||||
}
|
||||
|
||||
@Override
|
||||
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<Data> 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<Data> getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
private AbsStatusesAdapter<Data> mAdapter;
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
if (mPreferences != null) return mPreferences;
|
||||
return mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
private SimpleDrawerCallback mDrawerCallback;
|
||||
public abstract int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds);
|
||||
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@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<Data> extends BaseSupportFragment
|
|||
}
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
mAdapter.setEventListener(this);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
protected abstract AbsStatusesAdapter<Data> 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<Data> loader, Data data) {
|
||||
setRefreshing(false);
|
||||
mAdapter.setData(data);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Data> loader) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
triggerRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusActionClick(StatusViewHolder holder, int id, int position) {
|
||||
switch (id) {
|
||||
case R.id.reply_count: {
|
||||
final Context context = getActivity();
|
||||
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY);
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.putExtra(IntentConstants.EXTRA_STATUS, mAdapter.getStatus(position));
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
Utils.openStatus(getActivity(), mAdapter.getStatus(position), null);
|
||||
// final View cardView = holder.getCardView();
|
||||
// if (cardView != null && context instanceof FragmentActivity) {
|
||||
// final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
||||
// new Pair<>(cardView, StatusFragment.TRANSITION_NAME_CARD));
|
||||
// Utils.openStatus(context, getStatus(position), options);
|
||||
// } else {
|
||||
// Utils.openStatus(context, getStatus(position), null);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(GapViewHolder holder, int position) {
|
||||
final ParcelableStatus status = mAdapter.getStatus(position);
|
||||
final long sinceId = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(position + 1).id : -1;
|
||||
final long[] accountIds = {status.account_id};
|
||||
final long[] maxIds = {status.id};
|
||||
final long[] sinceIds = {sinceId};
|
||||
getStatuses(accountIds, maxIds, sinceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusMenuClick(StatusViewHolder holder, int position) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_STATUS, mAdapter.getStatus(position));
|
||||
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(getActivity().getSupportFragmentManager(), "status_menu");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -144,44 +248,36 @@ public abstract class AbsStatusesFragment<Data> 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<Data> loader, Data data) {
|
||||
setRefreshing(false);
|
||||
protected void setAdapterData(Data data) {
|
||||
mAdapter.setData(data);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Data> loader) {
|
||||
protected abstract AbsStatusesAdapter<Data> 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Cursor>,
|
||||
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<View, String>(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
||||
openUserProfile(activity, account.account_id, account.account_id,
|
||||
account.screen_name, activityOption);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> 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<Cursor> 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<Cursor> 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<View, String>(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<Cursor> loader) {
|
||||
mAccountsAdapter.changeCursor(null);
|
||||
public void onLoadingStarted(String imageUri, View view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<Cursor> 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<OptionItem> 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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.refreshnow.widget.OnRefreshListener;
|
||||
import org.mariotaku.refreshnow.widget.RefreshMode;
|
||||
import org.mariotaku.refreshnow.widget.RefreshNowConfig;
|
||||
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator;
|
||||
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator.IndicatorConfig;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.view.RefreshNowStaggeredGridView;
|
||||
|
||||
public abstract class BasePullToRefreshStaggeredGridFragment extends BaseSupportStaggeredGridFragment implements
|
||||
IBasePullToRefreshFragment, OnTouchListener {
|
||||
|
||||
@Override
|
||||
public RefreshNowStaggeredGridView getListView() {
|
||||
return (RefreshNowStaggeredGridView) super.getListView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefreshMode getRefreshMode() {
|
||||
if (getView() == null) return RefreshMode.NONE;
|
||||
return getListView().getRefreshMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRefreshing() {
|
||||
if (getView() == null) return false;
|
||||
return getListView().isRefreshing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide default implementation to return a simple list view. Subclasses
|
||||
* can override to replace with their own layout. If doing so, the returned
|
||||
* view hierarchy <em>must</em> have a ListView whose id is
|
||||
* {@link android.R.id#list android.R.id.list} and can optionally have a
|
||||
* sibling view id {@link android.R.id#empty android.R.id.empty} that is to
|
||||
* be shown when the list is empty.
|
||||
* <p>
|
||||
* If you are overriding this method with your own custom content, consider
|
||||
* including the standard layout {@link android.R.layout#list_content} in
|
||||
* your layout file, so that you continue to retain all of the standard
|
||||
* behavior of ListFragment. In particular, this is currently the only way
|
||||
* to have the built-in indeterminant progress state be shown.
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
|
||||
final FrameLayout root = new FrameLayout(context);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
final LinearLayout pframe = new LinearLayout(context);
|
||||
pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
|
||||
pframe.setOrientation(LinearLayout.VERTICAL);
|
||||
pframe.setVisibility(View.GONE);
|
||||
pframe.setGravity(Gravity.CENTER);
|
||||
|
||||
final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
|
||||
pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
final FrameLayout lframe = new FrameLayout(context);
|
||||
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
|
||||
|
||||
final TextView tv = new TextView(getActivity());
|
||||
tv.setId(INTERNAL_EMPTY_ID);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
final RefreshNowStaggeredGridView lv = (RefreshNowStaggeredGridView) inflater.inflate(
|
||||
R.layout.refreshnow_staggered_gridview, lframe, false);
|
||||
lv.setId(android.R.id.list);
|
||||
lv.setDrawSelectorOnTop(false);
|
||||
lv.setOnRefreshListener(this);
|
||||
lv.setOnTouchListener(this);
|
||||
lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
final RefreshNowProgressIndicator indicator = new RefreshNowProgressIndicator(context);
|
||||
final IndicatorConfig config = ThemeUtils.buildRefreshIndicatorConfig(context);
|
||||
indicator.setConfig(config);
|
||||
final int indicatorHeight = Math.round(3 * getResources().getDisplayMetrics().density);
|
||||
lframe.addView(indicator, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, indicatorHeight,
|
||||
Gravity.TOP));
|
||||
|
||||
lv.setRefreshIndicatorView(indicator);
|
||||
|
||||
root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshComplete() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRefreshStart(final RefreshMode mode) {
|
||||
if (mode.hasStart()) {
|
||||
onRefreshFromStart();
|
||||
} else if (mode.hasEnd()) {
|
||||
onRefreshFromEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouch(final View v, final MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
onListTouched();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfig(final RefreshNowConfig config) {
|
||||
if (getView() == null) return;
|
||||
getListView().setConfig(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnRefreshListener(final OnRefreshListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRefreshComplete() {
|
||||
if (getView() == null) return;
|
||||
getListView().setRefreshComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRefreshIndicatorView(final View view) {
|
||||
if (getView() == null) return;
|
||||
getListView().setRefreshIndicatorView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRefreshing(final boolean refresh) {
|
||||
if (getView() == null) return;
|
||||
getListView().setRefreshing(refresh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRefreshMode(final RefreshMode mode) {
|
||||
if (getView() == null) return;
|
||||
getListView().setRefreshMode(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean triggerRefresh() {
|
||||
onRefreshFromStart();
|
||||
setRefreshing(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void onListTouched() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -40,8 +40,8 @@ import android.widget.ListView;
|
|||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.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<Data> 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 {
|
||||
|
||||
|
|
|
@ -1,578 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MenuItem.OnMenuItemClickListener;
|
||||
import android.view.View;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.etsy.android.grid.StaggeredGridView;
|
||||
|
||||
import org.mariotaku.menucomponent.widget.PopupMenu;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.task.AsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTaskManager;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ClipboardUtils;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.PositionManager;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.collection.NoDuplicatesCopyOnWriteArrayList;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.cancelRetweet;
|
||||
import static org.mariotaku.twidere.util.Utils.clearListViewChoices;
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.setMenuForStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
||||
import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
||||
|
||||
abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefreshStaggeredGridFragment implements
|
||||
LoaderCallbacks<Data>, OnItemLongClickListener, OnMenuItemClickListener,
|
||||
MultiSelectManager.Callback, MenuButtonClickListener {
|
||||
|
||||
private AsyncTaskManager mAsyncTaskManager;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
private StaggeredGridView mListView;
|
||||
private IStatusesListAdapter<Data> mAdapter;
|
||||
private PopupMenu mPopupMenu;
|
||||
|
||||
private Data mData;
|
||||
private ParcelableStatus mSelectedStatus;
|
||||
|
||||
private boolean mLoadMoreAutomatically;
|
||||
private int mListScrollOffset;
|
||||
|
||||
private MultiSelectManager mMultiSelectManager;
|
||||
private PositionManager mPositionManager;
|
||||
|
||||
private int mFirstVisibleItem;
|
||||
private int mSelectedPosition;
|
||||
|
||||
private final Map<Long, Set<Long>> mUnreadCountsToRemove = Collections
|
||||
.synchronizedMap(new HashMap<Long, Set<Long>>());
|
||||
private final List<Integer> mReadPositions = new NoDuplicatesCopyOnWriteArrayList<Integer>();
|
||||
|
||||
private RemoveUnreadCountsTask<Data> mRemoveUnreadCountsTask;
|
||||
|
||||
public AsyncTaskManager getAsyncTaskManager() {
|
||||
return mAsyncTaskManager;
|
||||
}
|
||||
|
||||
public final Data getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatusesListAdapter<Data> getListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
public ParcelableStatus getSelectedStatus() {
|
||||
return mSelectedStatus;
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
return mPreferences;
|
||||
}
|
||||
|
||||
public abstract int getStatuses(long[] account_ids, long[] max_ids, long[] since_ids);
|
||||
|
||||
public final Map<Long, Set<Long>> getUnreadCountsToRemove() {
|
||||
return mUnreadCountsToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mAsyncTaskManager = getAsyncTaskManager();
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mPositionManager = new PositionManager(getActivity());
|
||||
mMultiSelectManager = getMultiSelectManager();
|
||||
mListView = getListView();
|
||||
mAdapter = newAdapterInstance();
|
||||
mAdapter.setMenuButtonClickListener(this);
|
||||
setListAdapter(null);
|
||||
setListHeaderFooters(mListView);
|
||||
setListAdapter(mAdapter);
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
mListView.setOnItemLongClickListener(this);
|
||||
setListShown(false);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Loader<Data> onCreateLoader(int id, Bundle args);
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position - mListView.getHeaderViewsCount());
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (holder.show_as_gap) return false;
|
||||
if (mPreferences.getBoolean(KEY_LONG_CLICK_TO_OPEN_MENU, false)) {
|
||||
openMenu(holder.content.getFakeOverflowButton(), status, position);
|
||||
} else {
|
||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemsCleared() {
|
||||
clearListViewChoices(mListView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(final Object item) {
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemUnselected(final Object item) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(final StaggeredGridView l, final View v, final int position, final long id) {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableStatus status = mAdapter.getStatus(pos);
|
||||
if (status == null) return;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (((StatusListViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
getStatuses(new long[]{status.account_id}, new long[]{status.id}, new long[]{since_id});
|
||||
mListView.setItemChecked(position, false);
|
||||
} else {
|
||||
if (mMultiSelectManager.isActive()) {
|
||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
||||
return;
|
||||
}
|
||||
openStatus(getActivity(), status, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onLoaderReset(final Loader<Data> loader) {
|
||||
mAdapter.setData(mData = null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onLoadFinished(final Loader<Data> loader, final Data data) {
|
||||
if (getActivity() == null || getView() == null) return;
|
||||
setListShown(true);
|
||||
setRefreshComplete();
|
||||
setProgressBarIndeterminateVisibility(false);
|
||||
setData(data);
|
||||
mFirstVisibleItem = -1;
|
||||
mReadPositions.clear();
|
||||
final int listVisiblePosition, savedChildIndex;
|
||||
final boolean rememberPosition = mPreferences.getBoolean(KEY_REMEMBER_POSITION, true);
|
||||
if (rememberPosition) {
|
||||
listVisiblePosition = mListView.getLastVisiblePosition();
|
||||
final int childCount = mListView.getChildCount();
|
||||
savedChildIndex = childCount - 1;
|
||||
if (childCount > 0) {
|
||||
final View lastChild = mListView.getChildAt(savedChildIndex);
|
||||
mListScrollOffset = lastChild != null ? lastChild.getTop() : 0;
|
||||
}
|
||||
} else {
|
||||
listVisiblePosition = mListView.getFirstVisiblePosition();
|
||||
savedChildIndex = 0;
|
||||
if (mListView.getChildCount() > 0) {
|
||||
final View firstChild = mListView.getChildAt(savedChildIndex);
|
||||
mListScrollOffset = firstChild != null ? firstChild.getTop() : 0;
|
||||
}
|
||||
}
|
||||
final long lastViewedId = mAdapter.getStatusId(listVisiblePosition);
|
||||
mAdapter.setData(data);
|
||||
mAdapter.setShowAccountColor(shouldShowAccountColor());
|
||||
final int currFirstVisiblePosition = mListView.getFirstVisiblePosition();
|
||||
final long currViewedId = mAdapter.getStatusId(currFirstVisiblePosition);
|
||||
final long statusId;
|
||||
if (lastViewedId <= 0) {
|
||||
if (!rememberPosition) return;
|
||||
statusId = mPositionManager.getPosition(getPositionKey());
|
||||
} else if ((listVisiblePosition > 0 || rememberPosition) && currViewedId > 0 && lastViewedId != currViewedId) {
|
||||
statusId = lastViewedId;
|
||||
} else {
|
||||
if (listVisiblePosition == 0 && mAdapter.getStatusId(0) != lastViewedId) {
|
||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int position = mAdapter.findPositionByStatusId(statusId);
|
||||
if (position > -1 && position < mListView.getCount()) {
|
||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
||||
// mListView.setSelectionFromTop(position, mListScrollOffset);
|
||||
mListView.setSelection(position);
|
||||
mListScrollOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMenuButtonClick(final View button, final int position, final long id) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position);
|
||||
if (status == null) return;
|
||||
openMenu(button, status, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onMenuItemClick(final MenuItem item) {
|
||||
final ParcelableStatus status = mSelectedStatus;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (status == null || twitter == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case MENU_VIEW: {
|
||||
openStatus(getActivity(), status, null);
|
||||
break;
|
||||
}
|
||||
case MENU_SHARE: {
|
||||
startStatusShareChooser(getActivity(), status);
|
||||
break;
|
||||
}
|
||||
case MENU_COPY: {
|
||||
if (ClipboardUtils.setText(getActivity(), status.text_plain)) {
|
||||
showOkMessage(getActivity(), R.string.text_copied, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_RETWEET: {
|
||||
if (isMyRetweet(status)) {
|
||||
cancelRetweet(twitter, status);
|
||||
} else {
|
||||
final long id_to_retweet = status.retweet_id > 0 ? status.retweet_id : status.id;
|
||||
twitter.retweetStatus(status.account_id, id_to_retweet);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_QUOTE: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA_STATUS, status);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_REPLY: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA_STATUS, status);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_FAVORITE: {
|
||||
if (status.is_favorite) {
|
||||
twitter.destroyFavoriteAsync(status.account_id, status.id);
|
||||
} else {
|
||||
twitter.createFavoriteAsync(status.account_id, status.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_DELETE: {
|
||||
twitter.destroyStatusAsync(status.account_id, status.id);
|
||||
break;
|
||||
}
|
||||
case MENU_ADD_TO_FILTER: {
|
||||
AddStatusFilterDialogFragment.show(getFragmentManager(), status);
|
||||
break;
|
||||
}
|
||||
case MENU_MULTI_SELECT: {
|
||||
final boolean isSelected = !mMultiSelectManager.isSelected(status);
|
||||
setItemSelected(status, mSelectedPosition, isSelected);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (item.getIntent() != null) {
|
||||
try {
|
||||
startActivity(item.getIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
if (mLoadMoreAutomatically) return;
|
||||
loadMoreStatuses();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
|
||||
configBaseCardAdapter(getActivity(), mAdapter);
|
||||
final boolean display_image_preview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
||||
final boolean display_sensitive_contents = mPreferences.getBoolean(KEY_DISPLAY_SENSITIVE_CONTENTS, false);
|
||||
final boolean indicate_my_status = mPreferences.getBoolean(KEY_INDICATE_MY_STATUS, true);
|
||||
mAdapter.setDisplayImagePreview(display_image_preview);
|
||||
mAdapter.setDisplaySensitiveContents(display_sensitive_contents);
|
||||
mAdapter.setIndicateMyStatusDisabled(isMyTimeline() || !indicate_my_status);
|
||||
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
||||
final int totalItemCount) {
|
||||
super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
|
||||
addReadPosition(firstVisibleItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
super.onScrollStateChanged(view, scrollState);
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_IDLE:
|
||||
for (int i = mListView.getFirstVisiblePosition(), j = mListView.getLastVisiblePosition(); i < j; i++) {
|
||||
mReadPositions.add(i);
|
||||
}
|
||||
removeUnreadCounts();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mMultiSelectManager.registerCallback(this);
|
||||
final int choiceMode = mListView.getChoiceMode();
|
||||
if (mMultiSelectManager.isActive()) {
|
||||
if (choiceMode != ListView.CHOICE_MODE_MULTIPLE) {
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
}
|
||||
} else {
|
||||
if (choiceMode != ListView.CHOICE_MODE_NONE) {
|
||||
Utils.clearListViewChoices(mListView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
savePosition();
|
||||
mMultiSelectManager.unregisterCallback(this);
|
||||
if (mPopupMenu != null) {
|
||||
mPopupMenu.dismiss();
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrollToStart() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
final int tab_position = getTabPosition();
|
||||
if (twitter != null && tab_position >= 0) {
|
||||
twitter.clearUnreadCountAsync(tab_position);
|
||||
}
|
||||
return super.scrollToStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
updateRefreshState();
|
||||
}
|
||||
|
||||
protected final int getListScrollOffset() {
|
||||
return mListScrollOffset;
|
||||
}
|
||||
|
||||
protected abstract long[] getNewestStatusIds();
|
||||
|
||||
protected abstract long[] getOldestStatusIds();
|
||||
|
||||
protected abstract String getPositionKey();
|
||||
|
||||
protected boolean isMyTimeline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void loadMoreStatuses();
|
||||
|
||||
protected abstract IStatusesListAdapter<Data> newAdapterInstance();
|
||||
|
||||
@Override
|
||||
protected void onReachedBottom() {
|
||||
if (!mLoadMoreAutomatically) return;
|
||||
loadMoreStatuses();
|
||||
}
|
||||
|
||||
protected void savePosition() {
|
||||
final int first_visible_position = mListView.getFirstVisiblePosition();
|
||||
if (mListView.getChildCount() > 0) {
|
||||
final View first_child = mListView.getChildAt(0);
|
||||
mListScrollOffset = first_child != null ? first_child.getTop() : 0;
|
||||
}
|
||||
final long status_id = mAdapter.getStatusId(first_visible_position);
|
||||
mPositionManager.setPosition(getPositionKey(), status_id);
|
||||
}
|
||||
|
||||
protected final void setData(final Data data) {
|
||||
mData = data;
|
||||
}
|
||||
|
||||
protected void setItemSelected(final ParcelableStatus status, final int position, final boolean selected) {
|
||||
if (selected) {
|
||||
mMultiSelectManager.selectItem(status);
|
||||
} else {
|
||||
mMultiSelectManager.unselectItem(status);
|
||||
}
|
||||
if (position >= 0) {
|
||||
mListView.setItemChecked(position, selected);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setListHeaderFooters(final StaggeredGridView list) {
|
||||
|
||||
}
|
||||
|
||||
protected boolean shouldEnablePullToRefresh() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract boolean shouldShowAccountColor();
|
||||
|
||||
protected abstract void updateRefreshState();
|
||||
|
||||
private void addReadPosition(final int firstVisibleItem) {
|
||||
if (mFirstVisibleItem != firstVisibleItem) {
|
||||
mReadPositions.add(firstVisibleItem);
|
||||
}
|
||||
mFirstVisibleItem = firstVisibleItem;
|
||||
}
|
||||
|
||||
private void addUnreadCountsToRemove(final long account_id, final long id) {
|
||||
if (mUnreadCountsToRemove.containsKey(account_id)) {
|
||||
final Set<Long> counts = mUnreadCountsToRemove.get(account_id);
|
||||
counts.add(id);
|
||||
} else {
|
||||
final Set<Long> counts = new HashSet<Long>();
|
||||
counts.add(id);
|
||||
mUnreadCountsToRemove.put(account_id, counts);
|
||||
}
|
||||
}
|
||||
|
||||
private void openMenu(final View view, final ParcelableStatus status, final int position) {
|
||||
mSelectedStatus = status;
|
||||
mSelectedPosition = position;
|
||||
if (view == null || status == null) return;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (mPopupMenu != null && mPopupMenu.isShowing()) {
|
||||
mPopupMenu.dismiss();
|
||||
}
|
||||
mPopupMenu = PopupMenu.getInstance(getActivity(), view);
|
||||
mPopupMenu.inflate(R.menu.action_status);
|
||||
final boolean longclickToOpenMenu = mPreferences.getBoolean(KEY_LONG_CLICK_TO_OPEN_MENU, false);
|
||||
final Menu menu = mPopupMenu.getMenu();
|
||||
setMenuForStatus(getActivity(), menu, status);
|
||||
Utils.setMenuItemAvailability(menu, MENU_MULTI_SELECT, longclickToOpenMenu);
|
||||
mPopupMenu.setOnMenuItemClickListener(this);
|
||||
mPopupMenu.show();
|
||||
}
|
||||
|
||||
private void removeUnreadCounts() {
|
||||
if (mRemoveUnreadCountsTask != null && mRemoveUnreadCountsTask.getStatus() == AsyncTask.Status.RUNNING)
|
||||
return;
|
||||
mRemoveUnreadCountsTask = new RemoveUnreadCountsTask<Data>(mReadPositions, this);
|
||||
mRemoveUnreadCountsTask.execute();
|
||||
}
|
||||
|
||||
static class RemoveUnreadCountsTask<T> extends AsyncTask<Void, Void, Void> {
|
||||
private final List<Integer> read_positions;
|
||||
private final IStatusesListAdapter<T> adapter;
|
||||
private final BaseStatusesStaggeredGridFragment<T> fragment;
|
||||
|
||||
RemoveUnreadCountsTask(final List<Integer> read_positions, final BaseStatusesStaggeredGridFragment<T> fragment) {
|
||||
this.read_positions = read_positions;
|
||||
this.fragment = fragment;
|
||||
this.adapter = fragment.getListAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
for (final int pos : read_positions) {
|
||||
final long id = adapter.getStatusId(pos), account_id = adapter.getAccountId(pos);
|
||||
fragment.addUnreadCountsToRemove(account_id, id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Void result) {
|
||||
final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.removeUnreadCountsAsync(fragment.getTabPosition(), fragment.getUnreadCountsToRemove());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -114,7 +114,8 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
|
|||
|
||||
@Override
|
||||
public int getTabPosition() {
|
||||
return 0;
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AbsListView.OnScrollListener;
|
||||
|
||||
import com.etsy.android.grid.StaggeredGridView;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment implements IBaseFragment, Constants,
|
||||
OnScrollListener, RefreshScrollTopInterface {
|
||||
|
||||
private boolean mActivityFirstCreated;
|
||||
private boolean mIsInstanceStateSaved;
|
||||
private boolean mReachedBottom, mNotReachedBottomBefore = true;
|
||||
|
||||
@Override
|
||||
public void requestFitSystemWindows() {
|
||||
final Activity activity = getActivity();
|
||||
final Fragment parentFragment = getParentFragment();
|
||||
final SystemWindowsInsetsCallback callback;
|
||||
if (parentFragment instanceof SystemWindowsInsetsCallback) {
|
||||
callback = (SystemWindowsInsetsCallback) parentFragment;
|
||||
} else if (activity instanceof SystemWindowsInsetsCallback) {
|
||||
callback = (SystemWindowsInsetsCallback) activity;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
final Rect insets = new Rect();
|
||||
if (callback.getSystemWindowsInsets(insets)) {
|
||||
fitSystemWindows(insets);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
|
||||
}
|
||||
|
||||
public final TwidereApplication getApplication() {
|
||||
return TwidereApplication.getInstance(getActivity());
|
||||
}
|
||||
|
||||
public final ContentResolver getContentResolver() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getContentResolver();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getExtraConfiguration() {
|
||||
final Bundle args = getArguments();
|
||||
final Bundle extras = new Bundle();
|
||||
if (args != null && args.containsKey(EXTRA_EXTRAS)) {
|
||||
extras.putAll(args.getBundle(EXTRA_EXTRAS));
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
|
||||
public final MultiSelectManager getMultiSelectManager() {
|
||||
return getApplication() != null ? getApplication().getMultiSelectManager() : null;
|
||||
}
|
||||
|
||||
public final SharedPreferences getSharedPreferences(final String name, final int mode) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSharedPreferences(name, mode);
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Object getSystemService(final String name) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) return activity.getSystemService(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getTabPosition() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1;
|
||||
}
|
||||
|
||||
public AsyncTwitterWrapper getTwitterWrapper() {
|
||||
return getApplication() != null ? getApplication().getTwitterWrapper() : null;
|
||||
}
|
||||
|
||||
public void invalidateOptionsMenu() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
public boolean isActivityFirstCreated() {
|
||||
return mActivityFirstCreated;
|
||||
}
|
||||
|
||||
public boolean isInstanceStateSaved() {
|
||||
return mIsInstanceStateSaved;
|
||||
}
|
||||
|
||||
public boolean isReachedBottom() {
|
||||
return mReachedBottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mIsInstanceStateSaved = savedInstanceState != null;
|
||||
final StaggeredGridView lv = getListView();
|
||||
lv.setOnScrollListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(final Activity activity) {
|
||||
super.onAttach(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mActivityFirstCreated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mActivityFirstCreated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
final Fragment fragment = getParentFragment();
|
||||
if (fragment instanceof SupportFragmentCallback) {
|
||||
((SupportFragmentCallback) fragment).onDetachFragment(this);
|
||||
}
|
||||
final Activity activity = getActivity();
|
||||
if (activity instanceof SupportFragmentCallback) {
|
||||
((SupportFragmentCallback) activity).onDetachFragment(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPostStart() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
||||
final int totalItemCount) {
|
||||
final boolean reached = firstVisibleItem + visibleItemCount >= totalItemCount
|
||||
&& totalItemCount >= visibleItemCount;
|
||||
|
||||
if (mReachedBottom != reached) {
|
||||
mReachedBottom = reached;
|
||||
if (mReachedBottom && mNotReachedBottomBefore) {
|
||||
mNotReachedBottomBefore = false;
|
||||
return;
|
||||
}
|
||||
if (mReachedBottom && getListAdapter().getCount() > visibleItemCount) {
|
||||
onReachedBottom();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
onPostStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mActivityFirstCreated = false;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
public void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrollToStart() {
|
||||
if (!isAdded() || getActivity() == null) return false;
|
||||
Utils.scrollListToTop(getListView());
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setProgressBarIndeterminateVisibility(final boolean visible) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.setProgressBarIndeterminateVisibility(visible);
|
||||
if (activity instanceof HomeActivity) {
|
||||
((HomeActivity) activity).setHomeProgressBarIndeterminateVisibility(visible);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(final int position) {
|
||||
Utils.scrollListToPosition(getListView(), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
final Activity activity = getActivity();
|
||||
final Fragment fragment = getParentFragment();
|
||||
if (fragment instanceof SupportFragmentCallback) {
|
||||
((SupportFragmentCallback) fragment).onSetUserVisibleHint(this, isVisibleToUser);
|
||||
}
|
||||
if (activity instanceof SupportFragmentCallback) {
|
||||
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean triggerRefresh() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void unregisterReceiver(final BroadcastReceiver receiver) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
protected void onReachedBottom() {
|
||||
|
||||
}
|
||||
}
|
|
@ -20,18 +20,134 @@
|
|||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
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<Cursor> {
|
||||
|
||||
|
||||
public abstract Uri getContentUri();
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
final Context context = getActivity();
|
||||
final Uri uri = getContentUri();
|
||||
final String table = getTableNameByUri(uri);
|
||||
final String sortOrder = getSortOrder();
|
||||
final long[] accountIds = getAccountIds();
|
||||
final Expression accountWhere = Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
|
||||
final Expression filterWhere = getFiltersWhere(table), where;
|
||||
if (filterWhere != null) {
|
||||
where = Expression.and(accountWhere, filterWhere);
|
||||
} else {
|
||||
where = accountWhere;
|
||||
}
|
||||
final String selection = processWhere(where).getSQL();
|
||||
return new CursorLoader(context, uri, Statuses.COLUMNS, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean triggerRefresh() {
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
result[0] = getAccountIds();
|
||||
result[2] = getNewestStatusIds(result[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long[] getAccountIds() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.getLong(EXTRA_ACCOUNT_ID) > 0) {
|
||||
return new long[]{args.getLong(EXTRA_ACCOUNT_ID)};
|
||||
}
|
||||
return Utils.getActivatedAccountIds(getActivity());
|
||||
}
|
||||
|
||||
protected abstract int getNotificationType();
|
||||
|
||||
@Override
|
||||
protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new CursorStatusesAdapter(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoadMoreStatuses() {
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
result[0] = getAccountIds();
|
||||
result[1] = getOldestStatusIds(result[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected Expression getFiltersWhere(String table) {
|
||||
if (!isFilterEnabled()) return null;
|
||||
return buildStatusFilterWhereClause(table, null, shouldEnableFiltersForRTs(getActivity()));
|
||||
}
|
||||
|
||||
protected abstract boolean isFilterEnabled();
|
||||
|
||||
protected long[] getNewestStatusIds(long[] accountIds) {
|
||||
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), accountIds);
|
||||
}
|
||||
|
||||
protected long[] getOldestStatusIds(long[] accountIds) {
|
||||
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), accountIds);
|
||||
}
|
||||
|
||||
protected Expression processWhere(final Expression where) {
|
||||
return where;
|
||||
}
|
||||
|
||||
private String getSortOrder() {
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
||||
return sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.Where;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.task.AsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
||||
import static org.mariotaku.twidere.util.Utils.shouldEnableFiltersForRTs;
|
||||
|
||||
public abstract class CursorStatusesListFragment extends BaseStatusesListFragment<Cursor> {
|
||||
|
||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
||||
this, 0, this);
|
||||
|
||||
public HomeActivity getHomeActivity() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity instanceof HomeActivity) return (HomeActivity) activity;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
getListAdapter().setFiltersEnabled(isFiltersEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||
final Context context = getActivity();
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
||||
final Uri uri = getContentUri();
|
||||
final String table = getTableNameByUri(uri);
|
||||
final String sortOrder = sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
||||
final long accountId = getAccountId();
|
||||
final long[] accountIds = accountId > 0 ? new long[]{accountId} : getActivatedAccountIds(context);
|
||||
final boolean noAccountSelected = accountIds.length == 0;
|
||||
setEmptyText(noAccountSelected ? getString(R.string.no_account_selected) : null);
|
||||
if (!noAccountSelected) {
|
||||
getListView().setEmptyView(null);
|
||||
}
|
||||
final Where accountWhere = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
|
||||
final Where where;
|
||||
if (isFiltersEnabled()) {
|
||||
final Where filterWhere = new Where(buildStatusFilterWhereClause(table, null,
|
||||
shouldEnableFiltersForRTs(context)));
|
||||
where = Where.and(accountWhere, filterWhere);
|
||||
} else {
|
||||
where = accountWhere;
|
||||
}
|
||||
final String selection = processWhere(where).getSQL();
|
||||
return new CursorLoader(context, uri, CursorStatusesListAdapter.CURSOR_COLS, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
savePosition();
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
final long account_id = getAccountId();
|
||||
result[0] = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
||||
result[2] = getNewestStatusIds();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestart() {
|
||||
super.onRestart();
|
||||
getLoaderManager().restartLoader(0, getArguments(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
super.onScrollStateChanged(view, scrollState);
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_FLING:
|
||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
||||
break;
|
||||
}
|
||||
case SCROLL_STATE_IDLE: {
|
||||
savePosition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.registerContentObserver(Filters.CONTENT_URI, true, mReloadContentObserver);
|
||||
if (getAccountId() <= 0) {
|
||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
savePosition();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
protected long getAccountId() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
|
||||
protected abstract Uri getContentUri();
|
||||
|
||||
@Override
|
||||
protected long[] getNewestStatusIds() {
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
||||
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
||||
}
|
||||
|
||||
protected abstract int getNotificationType();
|
||||
|
||||
@Override
|
||||
protected long[] getOldestStatusIds() {
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
||||
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
||||
}
|
||||
|
||||
protected abstract boolean isFiltersEnabled();
|
||||
|
||||
@Override
|
||||
protected void loadMoreStatuses() {
|
||||
if (isRefreshing()) return;
|
||||
savePosition();
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
final long account_id = getAccountId();
|
||||
result[0] = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
||||
result[1] = getOldestStatusIds();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CursorStatusesListAdapter newAdapterInstance(final boolean compact) {
|
||||
return new CursorStatusesListAdapter(getActivity(), compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListTouched() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.clearNotificationAsync(getNotificationType(), getAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
protected Where processWhere(final Where where) {
|
||||
return where;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return getAccountId() <= 0 && getActivatedAccountIds(getActivity()).length > 1;
|
||||
}
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
||||
import static org.mariotaku.twidere.util.Utils.shouldEnableFiltersForRTs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.Where;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.task.AsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
|
||||
|
||||
public abstract class CursorStatusesStaggeredGridFragment extends BaseStatusesStaggeredGridFragment<Cursor> {
|
||||
|
||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
||||
this, 0, this);
|
||||
|
||||
public HomeActivity getHomeActivity() {
|
||||
final Activity activity = getActivity();
|
||||
if (activity instanceof HomeActivity) return (HomeActivity) activity;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
getListAdapter().setFiltersEnabled(isFiltersEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||
final Uri uri = getContentUri();
|
||||
final String table = getTableNameByUri(uri);
|
||||
final String sort_by = Statuses.DEFAULT_SORT_ORDER;
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
final boolean no_account_selected = account_ids.length == 0;
|
||||
setEmptyText(no_account_selected ? getString(R.string.no_account_selected) : null);
|
||||
if (!no_account_selected) {
|
||||
getListView().setEmptyView(null);
|
||||
}
|
||||
final Where accountWhere = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
||||
final Where where;
|
||||
if (isFiltersEnabled()) {
|
||||
final Where filterWhere = new Where(buildStatusFilterWhereClause(table, null,
|
||||
shouldEnableFiltersForRTs(getActivity())));
|
||||
where = Where.and(accountWhere, filterWhere);
|
||||
} else {
|
||||
where = accountWhere;
|
||||
}
|
||||
return new CursorLoader(getActivity(), uri, CursorStatusesListAdapter.CURSOR_COLS, where.getSQL(), null, sort_by);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
savePosition();
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
final long account_id = getAccountId();
|
||||
result[0] = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
result[2] = getNewestStatusIds();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
super.onScrollStateChanged(view, scrollState);
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_FLING:
|
||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
||||
break;
|
||||
}
|
||||
case SCROLL_STATE_IDLE: {
|
||||
savePosition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.registerContentObserver(Filters.CONTENT_URI, true, mReloadContentObserver);
|
||||
if (getAccountId() <= 0) {
|
||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
savePosition();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
protected long getAccountId() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
|
||||
protected abstract Uri getContentUri();
|
||||
|
||||
@Override
|
||||
protected long[] getNewestStatusIds() {
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
return getNewestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
||||
}
|
||||
|
||||
protected abstract int getNotificationType();
|
||||
|
||||
@Override
|
||||
protected long[] getOldestStatusIds() {
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
return getOldestStatusIdsFromDatabase(getActivity(), getContentUri(), account_ids);
|
||||
}
|
||||
|
||||
protected abstract boolean isFiltersEnabled();
|
||||
|
||||
@Override
|
||||
protected void loadMoreStatuses() {
|
||||
if (isRefreshing()) return;
|
||||
savePosition();
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
final long account_id = getAccountId();
|
||||
result[0] = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
result[1] = getOldestStatusIds();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
getStatuses(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CursorStatusesListAdapter newAdapterInstance() {
|
||||
return new CursorStatusesListAdapter(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListTouched() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.clearNotificationAsync(getNotificationType(), getAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return getAccountId() <= 0 && getActivatedAccountIds(getActivity()).length > 1;
|
||||
}
|
||||
}
|
|
@ -64,7 +64,7 @@ import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
|
|||
import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter;
|
||||
import org.mariotaku.twidere.adapter.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<Account> accounts = Account.getAccountsList(getActivity(), false);
|
||||
final List<ParcelableAccount> 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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Cursor> 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class HomeTimelineListFragment extends CursorStatusesListFragment {
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
||||
setRefreshComplete();
|
||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return 0;
|
||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNotificationType() {
|
||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPositionKey() {
|
||||
return "home_timeline" + getTabPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFiltersEnabled() {
|
||||
final SharedPreferences pref = getSharedPreferences();
|
||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
||||
}
|
||||
|
||||
}
|
|
@ -5,8 +5,8 @@ import android.view.Menu;
|
|||
import android.view.MenuInflater;
|
||||
|
||||
import 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);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<List<ParcelableStatus>> {
|
||||
|
||||
@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<ParcelableStatus> data = getAdapterData();
|
||||
if (statusId <= 0 || data == null) return;
|
||||
final ArrayList<ParcelableStatus> dataToRemove = new ArrayList<>();
|
||||
for (final ParcelableStatus status : data) {
|
||||
if (status.id == statusId || status.retweet_id > 0 && status.retweet_id == statusId) {
|
||||
dataToRemove.add(status);
|
||||
}
|
||||
}
|
||||
data.removeAll(dataToRemove);
|
||||
setAdapterData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,4 +77,39 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
|||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long[] getAccountIds() {
|
||||
return new long[]{getAccountId()};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new ParcelableStatusesAdapter(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoadMoreStatuses() {
|
||||
final IStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||
final long[] maxIds = new long[]{adapter.getStatus(adapter.getStatusCount() - 1).id};
|
||||
getStatuses(null, maxIds, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean triggerRefresh() {
|
||||
final IStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||
final long[] accountIds = getAccountIds();
|
||||
if (adapter.getStatusCount() > 0) {
|
||||
final long[] sinceIds = new long[]{adapter.getStatus(0).id};
|
||||
getStatuses(accountIds, null, sinceIds);
|
||||
} else {
|
||||
getStatuses(accountIds, null, null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected long getAccountId() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
|||
if (statusId > 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.etsy.android.grid.StaggeredGridView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
/**
|
||||
* Static library support version of the framework's
|
||||
* {@link android.app.ListFragment}. Used to write apps that run on platforms
|
||||
* prior to Android 3.0. When running on Android 3.0 or above, this
|
||||
* implementation is still used; it does not try to switch to the framework's
|
||||
* implementation. See the framework SDK documentation for a class overview.
|
||||
*/
|
||||
public class StaggeredGridFragment extends Fragment {
|
||||
static final int INTERNAL_EMPTY_ID = 0x00ff0001;
|
||||
static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
|
||||
static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
|
||||
|
||||
final private Handler mHandler = new Handler();
|
||||
|
||||
final private Runnable mRequestFocus = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mList.focusableViewAvailable(mList);
|
||||
}
|
||||
};
|
||||
|
||||
final private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(final AdapterView<?> parent, final View v, final int position, final long id) {
|
||||
onListItemClick((StaggeredGridView) parent, v, position, id);
|
||||
}
|
||||
};
|
||||
|
||||
ListAdapter mAdapter;
|
||||
StaggeredGridView mList;
|
||||
View mEmptyView;
|
||||
TextView mStandardEmptyView;
|
||||
View mProgressContainer;
|
||||
View mListContainer;
|
||||
CharSequence mEmptyText;
|
||||
boolean mListShown;
|
||||
|
||||
public StaggeredGridFragment() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ListAdapter associated with this activity's ListView.
|
||||
*/
|
||||
public ListAdapter getListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity's list view widget.
|
||||
*/
|
||||
public StaggeredGridView getListView() {
|
||||
ensureList();
|
||||
return mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cursor row ID of the currently selected list item.
|
||||
*/
|
||||
public long getSelectedItemId() {
|
||||
ensureList();
|
||||
return mList.getSelectedItemId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the currently selected list item.
|
||||
*/
|
||||
public int getSelectedItemPosition() {
|
||||
ensureList();
|
||||
return mList.getSelectedItemPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide default implementation to return a simple list view. Subclasses
|
||||
* can override to replace with their own layout. If doing so, the returned
|
||||
* view hierarchy <em>must</em> have a ListView whose id is
|
||||
* {@link android.R.id#list android.R.id.list} and can optionally have a
|
||||
* sibling view id {@link android.R.id#empty android.R.id.empty} that is to
|
||||
* be shown when the list is empty.
|
||||
*
|
||||
* <p>
|
||||
* If you are overriding this method with your own custom content, consider
|
||||
* including the standard layout {@link android.R.layout#list_content} in
|
||||
* your layout file, so that you continue to retain all of the standard
|
||||
* behavior of ListFragment. In particular, this is currently the only way
|
||||
* to have the built-in indeterminant progress state be shown.
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
|
||||
final FrameLayout root = new FrameLayout(context);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
final LinearLayout pframe = new LinearLayout(context);
|
||||
pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
|
||||
pframe.setOrientation(LinearLayout.VERTICAL);
|
||||
pframe.setVisibility(View.GONE);
|
||||
pframe.setGravity(Gravity.CENTER);
|
||||
|
||||
final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
|
||||
pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
final FrameLayout lframe = new FrameLayout(context);
|
||||
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
|
||||
|
||||
final TextView tv = new TextView(getActivity());
|
||||
tv.setId(INTERNAL_EMPTY_ID);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
final StaggeredGridView lv = (StaggeredGridView) inflater.inflate(R.layout.staggered_gridview, lframe, false);
|
||||
lv.setId(android.R.id.list);
|
||||
lv.setDrawSelectorOnTop(false);
|
||||
lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach from list view.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mHandler.removeCallbacks(mRequestFocus);
|
||||
mList = null;
|
||||
mListShown = false;
|
||||
mEmptyView = mProgressContainer = mListContainer = null;
|
||||
mStandardEmptyView = null;
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called when an item in the list is selected.
|
||||
* Subclasses should override. Subclasses can call
|
||||
* getListView().getItemAtPosition(position) if they need to access the data
|
||||
* associated with the selected item.
|
||||
*
|
||||
* @param l The ListView where the click happened
|
||||
* @param v The view that was clicked within the ListView
|
||||
* @param position The position of the view in the list
|
||||
* @param id The row id of the item that was clicked
|
||||
*/
|
||||
public void onListItemClick(final StaggeredGridView l, final View v, final int position, final long id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach to list view once the view hierarchy has been created.
|
||||
*/
|
||||
@Override
|
||||
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
ensureList();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default content for a ListFragment has a TextView that can be shown
|
||||
* when the list is empty. If you would like to have it shown, call this
|
||||
* method to supply the text it should use.
|
||||
*/
|
||||
public void setEmptyText(final CharSequence text) {
|
||||
ensureList();
|
||||
if (mStandardEmptyView == null) throw new IllegalStateException("Can't be used with a custom content view");
|
||||
mStandardEmptyView.setText(text);
|
||||
if (mEmptyText == null) {
|
||||
mList.setEmptyView(mStandardEmptyView);
|
||||
}
|
||||
mEmptyText = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the cursor for the list view.
|
||||
*/
|
||||
public void setListAdapter(final ListAdapter adapter) {
|
||||
final boolean hadAdapter = mAdapter != null;
|
||||
mAdapter = adapter;
|
||||
if (mList != null) {
|
||||
mList.setAdapter(adapter);
|
||||
if (!mListShown && !hadAdapter) {
|
||||
// The list was hidden, and previously didn't have an
|
||||
// adapter. It is now time to show it.
|
||||
setListShown(true, getView().getWindowToken() != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Control whether the list is being displayed. You can make it not
|
||||
* displayed if you are waiting for the initial data to show in it. During
|
||||
* this time an indeterminant progress indicator will be shown instead.
|
||||
*
|
||||
* <p>
|
||||
* Applications do not normally need to use this themselves. The default
|
||||
* behavior of ListFragment is to start with the list not being shown, only
|
||||
* showing it once an adapter is given with
|
||||
* {@link #setListAdapter(ListAdapter)}. If the list at that point had not
|
||||
* been shown, when it does get shown it will be do without the user ever
|
||||
* seeing the hidden state.
|
||||
*
|
||||
* @param shown If true, the list view is shown; if false, the progress
|
||||
* indicator. The initial value is true.
|
||||
*/
|
||||
public void setListShown(final boolean shown) {
|
||||
setListShown(shown, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #setListShown(boolean)}, but no animation is used when
|
||||
* transitioning from the previous state.
|
||||
*/
|
||||
public void setListShownNoAnimation(final boolean shown) {
|
||||
setListShown(shown, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the currently selected list item to the specified position with the
|
||||
* adapter's data
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
public void setSelection(final int position) {
|
||||
ensureList();
|
||||
mList.setSelection(position);
|
||||
}
|
||||
|
||||
private void ensureList() {
|
||||
if (mList != null) return;
|
||||
final View root = getView();
|
||||
if (root == null) throw new IllegalStateException("Content view not yet created");
|
||||
if (root instanceof StaggeredGridView) {
|
||||
mList = (StaggeredGridView) root;
|
||||
} else {
|
||||
mStandardEmptyView = (TextView) root.findViewById(INTERNAL_EMPTY_ID);
|
||||
if (mStandardEmptyView == null) {
|
||||
mEmptyView = root.findViewById(android.R.id.empty);
|
||||
} else {
|
||||
mStandardEmptyView.setVisibility(View.GONE);
|
||||
}
|
||||
mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID);
|
||||
mListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);
|
||||
final View rawListView = root.findViewById(android.R.id.list);
|
||||
if (!(rawListView instanceof StaggeredGridView)) {
|
||||
if (rawListView == null)
|
||||
throw new RuntimeException("Your content must have a StaggeredGridView whose id attribute is "
|
||||
+ "'android.R.id.list'");
|
||||
throw new RuntimeException("Content has view with id attribute 'android.R.id.list' "
|
||||
+ "that is not a StaggeredGridView class");
|
||||
}
|
||||
mList = (StaggeredGridView) rawListView;
|
||||
if (mEmptyView != null) {
|
||||
mList.setEmptyView(mEmptyView);
|
||||
} else if (mEmptyText != null) {
|
||||
mStandardEmptyView.setText(mEmptyText);
|
||||
mList.setEmptyView(mStandardEmptyView);
|
||||
}
|
||||
}
|
||||
mListShown = true;
|
||||
mList.setOnItemClickListener(mOnClickListener);
|
||||
if (mAdapter != null) {
|
||||
final ListAdapter adapter = mAdapter;
|
||||
mAdapter = null;
|
||||
setListAdapter(adapter);
|
||||
} else {
|
||||
// We are starting without an adapter, so assume we won't
|
||||
// have our data right away and start with the progress indicator.
|
||||
if (mProgressContainer != null) {
|
||||
setListShown(false, false);
|
||||
}
|
||||
}
|
||||
mHandler.post(mRequestFocus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Control whether the list is being displayed. You can make it not
|
||||
* displayed if you are waiting for the initial data to show in it. During
|
||||
* this time an indeterminant progress indicator will be shown instead.
|
||||
*
|
||||
* @param shown If true, the list view is shown; if false, the progress
|
||||
* indicator. The initial value is true.
|
||||
* @param animate If true, an animation will be used to transition to the
|
||||
* new state.
|
||||
*/
|
||||
private void setListShown(final boolean shown, final boolean animate) {
|
||||
ensureList();
|
||||
if (mProgressContainer == null) throw new IllegalStateException("Can't be used with a custom content view");
|
||||
if (mListShown == shown) return;
|
||||
mListShown = shown;
|
||||
if (shown) {
|
||||
if (animate) {
|
||||
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
|
||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
|
||||
} else {
|
||||
mProgressContainer.clearAnimation();
|
||||
mListContainer.clearAnimation();
|
||||
}
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mListContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (animate) {
|
||||
mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
|
||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
|
||||
} else {
|
||||
mProgressContainer.clearAnimation();
|
||||
mListContainer.clearAnimation();
|
||||
}
|
||||
mProgressContainer.setVisibility(View.VISIBLE);
|
||||
mListContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.view.View;
|
||||
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class StaggeredHomeTimelineFragment extends CursorStatusesStaggeredGridFragment {
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
||||
setRefreshComplete();
|
||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return 0;
|
||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNotificationType() {
|
||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPositionKey() {
|
||||
return "home_timeline" + getTabPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFiltersEnabled() {
|
||||
final SharedPreferences pref = getSharedPreferences();
|
||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getRefreshIndicatorView() {
|
||||
return getListView().getRefreshIndicatorView();
|
||||
}
|
||||
}
|
|
@ -74,8 +74,8 @@ import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
|||
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
||||
import org.mariotaku.twidere.adapter.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 {
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ public class UserFavoritesFragment extends ParcelableStatusesFragment {
|
|||
@Override
|
||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||
setRefreshing(true);
|
||||
final List<ParcelableStatus> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<SingleResponse<ParcelableUserList>>, 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
|
||||
|
|
|
@ -1,75 +1,51 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserListTimelineFragment extends ParcelableStatusesListFragment {
|
||||
/**
|
||||
* Created by mariotaku on 14/12/2.
|
||||
*/
|
||||
public class UserListTimelineFragment extends ParcelableStatusesFragment {
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserListTimelineLoader(getActivity(), account_id, list_id, user_id, screen_name, list_name, max_id,
|
||||
since_id, getData(), getSavedStatusesFileArgs(), tab_position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setFiltersEnabled(true);
|
||||
adapter.setIgnoredFilterFields(false, false, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||
return new String[] { AUTHORITY_USER_LIST_TIMELINE, "account" + account_id, "list_id" + list_id,
|
||||
"list_name" + list_name, "user" + user_id, "screen_name" + screen_name };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserListTimelineLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserListTimelineListFragment extends ParcelableStatusesListFragment {
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserListTimelineLoader(getActivity(), account_id, list_id, user_id, screen_name, list_name, max_id,
|
||||
since_id, getData(), getSavedStatusesFileArgs(), tab_position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setFiltersEnabled(true);
|
||||
adapter.setIgnoredFilterFields(false, false, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final int list_id = args.getInt(EXTRA_LIST_ID, -1);
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final String list_name = args.getString(EXTRA_LIST_NAME);
|
||||
return new String[] { AUTHORITY_USER_LIST_TIMELINE, "account" + account_id, "list_id" + list_id,
|
||||
"list_name" + list_name, "user" + user_id, "screen_name" + screen_name };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,19 +9,19 @@ import android.view.SubMenu;
|
|||
import android.view.View;
|
||||
|
||||
import 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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.support.ActivitiesAboutMeFragment;
|
||||
import org.mariotaku.twidere.fragment.support.ActivitiesByFriendsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineListFragment;
|
||||
import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.SearchStatusesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public enum CustomTabConfiguration2 implements Constants {
|
||||
|
||||
HOME_TIMELINE(HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false),
|
||||
|
||||
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false),
|
||||
|
||||
DIRECT_MESSAGES(DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false),
|
||||
|
||||
TRENDS_SUGGESTIONS(TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true),
|
||||
|
||||
FAVORITES(UserFavoritesFragment.class, R.string.favorites, R.drawable.ic_action_star,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 4),
|
||||
|
||||
USER_TIMELINE(UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5),
|
||||
|
||||
SEARCH_STATUSES(SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
||||
EXTRA_QUERY, 6),
|
||||
|
||||
LIST_TIMELINE(UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7),
|
||||
|
||||
ACTIVITIES_ABOUT_ME(ActivitiesAboutMeFragment.class, R.string.activities_about_me,
|
||||
R.drawable.ic_action_user, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 8),
|
||||
|
||||
ACTIVITIES_BY_FRIENDS(ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9);
|
||||
|
||||
public static final int FIELD_TYPE_NONE = 0;
|
||||
public static final int FIELD_TYPE_USER = 1;
|
||||
public static final int FIELD_TYPE_USER_LIST = 2;
|
||||
public static final int FIELD_TYPE_TEXT = 3;
|
||||
|
||||
public static final int ACCOUNT_NONE = 0;
|
||||
public static final int ACCOUNT_REQUIRED = 1;
|
||||
public static final int ACCOUNT_OPTIONAL = 2;
|
||||
|
||||
private final int title, icon, secondaryFieldType, secondaryFieldTitle, sortPosition, accountRequirement;
|
||||
private final Class<? extends Fragment> cls;
|
||||
private final String secondaryFieldTextKey;
|
||||
private final boolean singleTab;
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, false);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition, final boolean singleTab) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, singleTab);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, secondaryFieldTextKey, sortPosition, false);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition, final boolean singleTab) {
|
||||
this.cls = cls;
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.sortPosition = sortPosition;
|
||||
this.accountRequirement = accountRequirement;
|
||||
this.secondaryFieldType = secondaryFieldType;
|
||||
this.secondaryFieldTitle = secondaryFieldTitle;
|
||||
this.secondaryFieldTextKey = secondaryFieldTextKey;
|
||||
this.singleTab = singleTab;
|
||||
}
|
||||
|
||||
public int getAccountRequirement() {
|
||||
return accountRequirement;
|
||||
}
|
||||
|
||||
public int getDefaultIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int getDefaultTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Class<? extends Fragment> getFragmentClass() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public String getSecondaryFieldTextKey() {
|
||||
return secondaryFieldTextKey;
|
||||
}
|
||||
|
||||
public int getSecondaryFieldTitle() {
|
||||
return secondaryFieldTitle;
|
||||
}
|
||||
|
||||
public int getSecondaryFieldType() {
|
||||
return secondaryFieldType;
|
||||
}
|
||||
|
||||
public int getSortPosition() {
|
||||
return sortPosition;
|
||||
}
|
||||
|
||||
public boolean isSingleTab() {
|
||||
return singleTab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomTabConfiguration{title=" + title + ", icon=" + icon + ", secondaryFieldType="
|
||||
+ secondaryFieldType + ", secondaryFieldTitle=" + secondaryFieldTitle + ", sortPosition="
|
||||
+ sortPosition + ", accountRequirement=" + accountRequirement + ", cls=" + cls
|
||||
+ ", secondaryFieldTextKey=" + secondaryFieldTextKey + ", singleTab=" + singleTab + "}";
|
||||
}
|
||||
|
||||
public static class CustomTabConfigurationComparator implements Comparator<Entry<String, CustomTabConfiguration2>> {
|
||||
|
||||
public static final CustomTabConfigurationComparator SINGLETON = new CustomTabConfigurationComparator();
|
||||
|
||||
@Override
|
||||
public int compare(final Entry<String, CustomTabConfiguration2> lhs,
|
||||
final Entry<String, CustomTabConfiguration2> rhs) {
|
||||
return lhs.getValue().getSortPosition() - rhs.getValue().getSortPosition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -80,7 +80,7 @@ public class DraftItem implements Parcelable {
|
|||
|
||||
public DraftItem(final ParcelableStatusUpdate status) {
|
||||
_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;
|
||||
|
|
|
@ -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<Account> CREATOR = new Parcelable.Creator<Account>() {
|
||||
public static final Parcelable.Creator<ParcelableAccount> CREATOR = new Parcelable.Creator<ParcelableAccount>() {
|
||||
|
||||
@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<Account> list = getAccountsList(context, activatedOnly, officialKeyOnly);
|
||||
return list.toArray(new Account[list.size()]);
|
||||
final List<ParcelableAccount> 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<Account> getAccountsList(final Context context, final boolean activatedOnly) {
|
||||
public static List<ParcelableAccount> getAccountsList(final Context context, final boolean activatedOnly) {
|
||||
return getAccountsList(context, activatedOnly, false);
|
||||
}
|
||||
|
||||
public static List<Account> getAccountsList(final Context context, final boolean activatedOnly,
|
||||
public static List<ParcelableAccount> getAccountsList(final Context context, final boolean activatedOnly,
|
||||
final boolean officialKeyOnly) {
|
||||
if (context == null) return Collections.emptyList();
|
||||
final ArrayList<Account> accounts = new ArrayList<>();
|
||||
final ArrayList<ParcelableAccount> accounts = new ArrayList<>();
|
||||
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(),
|
||||
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;
|
|
@ -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 {
|
|||
* <b>ParcelableStatusUpdate.Builder</b> 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;
|
||||
}
|
||||
|
|
|
@ -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<Account> accounts) {
|
||||
public void setAccountsData(final List<ParcelableAccount> 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<Void, Void, List<Account>> {
|
||||
private static class LoadAccountsTask extends AsyncTask<Void, Void, List<ParcelableAccount>> {
|
||||
|
||||
private final AccountsListPreference mPreference;
|
||||
|
||||
|
@ -224,12 +222,12 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<Account> doInBackground(final Void... params) {
|
||||
return Account.getAccountsList(mPreference.getContext(), false);
|
||||
protected List<ParcelableAccount> doInBackground(final Void... params) {
|
||||
return ParcelableAccount.getAccountsList(mPreference.getContext(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final List<Account> result) {
|
||||
protected void onPostExecute(final List<ParcelableAccount> result) {
|
||||
mPreference.setAccountsData(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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: {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue