diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/RequestType.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/RequestType.java
index a9b79630c..cc94a90ad 100644
--- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/RequestType.java
+++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/RequestType.java
@@ -23,15 +23,29 @@ package org.mariotaku.twidere.model;
* Created by mariotaku on 15/6/24.
*/
public enum RequestType {
- API("api"), MEDIA("media"), USAGE_STATISTICS("usage_statistics");
+ OTHER("other", 0), API("api", 1), MEDIA("media", 2), USAGE_STATISTICS("usage_statistics", 3);
+
+ private final int value;
+
+ private final String name;
public String getName() {
return name;
}
- private final String name;
+ public int getValue() {
+ return value;
+ }
- RequestType(String name) {
+ RequestType(String name, int value) {
this.name = name;
+ this.value = value;
+ }
+
+ public static int getValue(String name) {
+ if ("api".equalsIgnoreCase(name)) return API.getValue();
+ else if ("media".equalsIgnoreCase(name)) return MEDIA.getValue();
+ else if ("usage_statistics".equalsIgnoreCase(name)) return USAGE_STATISTICS.getValue();
+ return OTHER.getValue();
}
}
diff --git a/twidere.component.querybuilder/src/main/java/org/mariotaku/querybuilder/Expression.java b/twidere.component.querybuilder/src/main/java/org/mariotaku/querybuilder/Expression.java
index 69d742e01..b69efe436 100644
--- a/twidere.component.querybuilder/src/main/java/org/mariotaku/querybuilder/Expression.java
+++ b/twidere.component.querybuilder/src/main/java/org/mariotaku/querybuilder/Expression.java
@@ -1,11 +1,11 @@
/**
* This is free and unencumbered software released into the public domain.
- *
+ *
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
- *
+ *
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
@@ -13,7 +13,7 @@
* 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.
@@ -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
*/
@@ -74,6 +74,19 @@ public class Expression implements SQLLang {
return new Expression(String.format(Locale.ROOT, "%s > %d", l, r));
}
+
+ public static Expression greaterEquals(final String l, final long r) {
+ return new Expression(String.format(Locale.ROOT, "%s >= %d", l, r));
+ }
+
+ public static Expression lesserEquals(final String l, final long r) {
+ return new Expression(String.format(Locale.ROOT, "%s <= %d", l, r));
+ }
+
+ public static Expression lesserThan(final String l, final long r) {
+ return new Expression(String.format(Locale.ROOT, "%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()));
}
@@ -129,7 +142,6 @@ public class Expression implements SQLLang {
}
-
public static Expression like(final Column column, final SQLLang expression) {
return new Expression(String.format(Locale.ROOT, "%s LIKE %s", column.getSQL(), expression.getSQL()));
}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/NetworkUsageInfo.java b/twidere/src/main/java/org/mariotaku/twidere/model/NetworkUsageInfo.java
new file mode 100644
index 000000000..e9a926f9d
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/model/NetworkUsageInfo.java
@@ -0,0 +1,124 @@
+/*
+ * Twidere - Twitter client for Android
+ *
+ * Copyright (C) 2012-2015 Mariotaku Lee
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.mariotaku.twidere.model;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Color;
+
+import com.db.chart.model.BarSet;
+import com.db.chart.model.ChartSet;
+
+import org.mariotaku.querybuilder.Expression;
+import org.mariotaku.twidere.preference.NetworkUsageSummaryPreferences;
+import org.mariotaku.twidere.provider.TwidereDataStore;
+import org.mariotaku.twidere.util.MathUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by mariotaku on 15/6/25.
+ */
+public class NetworkUsageInfo {
+ private final double totalSent;
+ private final double totalReceived;
+ private final ArrayList chartData;
+ private final double dayMax;
+
+ public NetworkUsageInfo(ArrayList chartData, double totalReceived, double totalSent, double dayMax) {
+ this.chartData = chartData;
+ this.totalReceived = totalReceived;
+ this.totalSent = totalSent;
+ this.dayMax = dayMax;
+ }
+
+ public static NetworkUsageInfo get(Context context, Date start, Date end) {
+ final ContentResolver cr = context.getContentResolver();
+ final long startTime = TimeUnit.HOURS.convert(start.getTime(), TimeUnit.MILLISECONDS);
+ final long endTime = TimeUnit.HOURS.convert(end.getTime(), TimeUnit.MILLISECONDS);
+ final Expression where = Expression.and(Expression.greaterEquals(TwidereDataStore.NetworkUsages.TIME_IN_HOURS, startTime),
+ Expression.lesserThan(TwidereDataStore.NetworkUsages.TIME_IN_HOURS, endTime));
+ final int days = (int) TimeUnit.DAYS.convert(endTime - startTime, TimeUnit.HOURS);
+ final Cursor c = cr.query(TwidereDataStore.NetworkUsages.CONTENT_URI, TwidereDataStore.NetworkUsages.COLUMNS,
+ where.getSQL(), null, TwidereDataStore.NetworkUsages.TIME_IN_HOURS);
+ final int idxDate = c.getColumnIndex(TwidereDataStore.NetworkUsages.TIME_IN_HOURS);
+ final int idxSent = c.getColumnIndex(TwidereDataStore.NetworkUsages.KILOBYTES_SENT);
+ final int idxReceived = c.getColumnIndex(TwidereDataStore.NetworkUsages.KILOBYTES_RECEIVED);
+ final int idxType = c.getColumnIndex(TwidereDataStore.NetworkUsages.REQUEST_TYPE);
+ final double[][] usageArray = new double[days][RequestType.values().length];
+ double totalReceived = 0, totalSent = 0;
+ c.moveToFirst();
+ while (!c.isAfterLast()) {
+ final long hours = c.getLong(idxDate);
+ final int idx = (int) TimeUnit.DAYS.convert((hours - startTime), TimeUnit.HOURS);
+ final double sent = c.getDouble(idxSent);
+ final double received = c.getDouble(idxReceived);
+ final String type = c.getString(idxType);
+ usageArray[idx][RequestType.getValue(type)] += (sent + received);
+ totalReceived += received;
+ totalSent += sent;
+ c.moveToNext();
+ }
+ c.close();
+
+ final BarSet apiSet = new BarSet();
+ final BarSet mediaSet = new BarSet();
+ final BarSet usageStatisticsSet = new BarSet();
+
+ double dayMax = 0;
+ for (int i = 0; i < days; i++) {
+ String day = String.valueOf(i + 1);
+ final double[] dayUsage = usageArray[i];
+ apiSet.addBar(day, (float) dayUsage[RequestType.API.getValue()]);
+ mediaSet.addBar(day, (float) dayUsage[RequestType.MEDIA.getValue()]);
+ usageStatisticsSet.addBar(day, (float) dayUsage[RequestType.USAGE_STATISTICS.getValue()]);
+ dayMax = Math.max(dayMax, MathUtils.sum(dayUsage));
+ }
+
+ apiSet.setColor(Color.RED);
+ mediaSet.setColor(Color.GREEN);
+ usageStatisticsSet.setColor(Color.BLUE);
+
+ final ArrayList data = new ArrayList<>();
+ data.add(apiSet);
+ data.add(mediaSet);
+ data.add(usageStatisticsSet);
+ return new NetworkUsageInfo(data, totalReceived, totalSent, dayMax);
+ }
+
+ public double getDayMax() {
+ return dayMax;
+ }
+
+ public double getTotalSent() {
+ return totalSent;
+ }
+
+ public double getTotalReceived() {
+ return totalReceived;
+ }
+
+ public ArrayList getChartData() {
+ return chartData;
+ }
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/NetworkUsageSummaryPreferences.java b/twidere/src/main/java/org/mariotaku/twidere/preference/NetworkUsageSummaryPreferences.java
new file mode 100644
index 000000000..4eb75d8bf
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/preference/NetworkUsageSummaryPreferences.java
@@ -0,0 +1,119 @@
+/*
+ * Twidere - Twitter client for Android
+ *
+ * Copyright (C) 2012-2015 Mariotaku Lee
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.mariotaku.twidere.preference;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.db.chart.model.ChartSet;
+import com.db.chart.view.AxisController;
+import com.db.chart.view.StackBarChartView;
+import com.desmond.asyncmanager.AsyncManager;
+import com.desmond.asyncmanager.TaskRunnable;
+
+import org.apache.commons.lang3.tuple.Triple;
+import org.mariotaku.twidere.R;
+import org.mariotaku.twidere.model.NetworkUsageInfo;
+import org.mariotaku.twidere.util.Utils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * Created by mariotaku on 15/6/24.
+ */
+public class NetworkUsageSummaryPreferences extends Preference {
+
+ private StackBarChartView mChartView;
+ private NetworkUsageInfo mUsage;
+ private TextView mTotalUsage;
+
+ public NetworkUsageSummaryPreferences(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setLayoutResource(R.layout.layout_preference_network_usage);
+ getUsageInfo();
+ }
+
+ public NetworkUsageSummaryPreferences(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.preferenceStyle);
+ }
+
+ public NetworkUsageSummaryPreferences(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ protected View onCreateView(ViewGroup parent) {
+ final View view = super.onCreateView(parent);
+ mChartView = (StackBarChartView) view.findViewById(R.id.chart);
+ mTotalUsage = (TextView) view.findViewById(R.id.total_usage);
+ mChartView.setXLabels(AxisController.LabelPosition.NONE);
+ mChartView.setYLabels(AxisController.LabelPosition.NONE);
+ return view;
+ }
+
+ private void getUsageInfo() {
+ final Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH));
+ final Date start = cal.getTime();
+ cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH));
+ final Date end = cal.getTime();
+ TaskRunnable, NetworkUsageInfo, NetworkUsageSummaryPreferences> task;
+ task = new TaskRunnable, NetworkUsageInfo, NetworkUsageSummaryPreferences>() {
+ @Override
+ public NetworkUsageInfo doLongOperation(Triple params) throws InterruptedException {
+ return NetworkUsageInfo.get(params.getLeft(), params.getMiddle(), params.getRight());
+ }
+
+ @Override
+ public void callback(NetworkUsageSummaryPreferences handler, NetworkUsageInfo result) {
+ handler.setUsage(result);
+ }
+ };
+ task.setResultHandler(this);
+ task.setParams(Triple.of(getContext(), start, end));
+ AsyncManager.runBackgroundTask(task);
+ }
+
+ private void setUsage(NetworkUsageInfo usage) {
+ mUsage = usage;
+ notifyChanged();
+ }
+
+ @Override
+ protected void onBindView(@NonNull View view) {
+ super.onBindView(view);
+ final NetworkUsageInfo usage = mUsage;
+ if (usage == null) return;
+ final ArrayList chartData = usage.getChartData();
+ if (mChartView.getData() != chartData) {
+ mChartView.addData(chartData);
+ mChartView.show();
+ }
+ mTotalUsage.setText(Utils.calculateProperSize((usage.getTotalSent() + usage.getTotalReceived()) * 1024));
+ }
+
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemePreviewPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/ThemePreviewPreference.java
deleted file mode 100644
index 9c1d17ee9..000000000
--- a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemePreviewPreference.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Twidere - Twitter client for Android
- *
- * Copyright (C) 2012-2014 Mariotaku Lee
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.mariotaku.twidere.preference;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.preference.Preference;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.internal.view.SupportMenuInflater;
-import android.support.v7.widget.ActionMenuView;
-import android.support.v7.widget.CardView;
-import android.support.v7.widget.Toolbar;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-import android.view.InflateException;
-import android.view.LayoutInflater;
-import android.view.MenuInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.mariotaku.twidere.Constants;
-import org.mariotaku.twidere.R;
-import org.mariotaku.twidere.util.ThemeUtils;
-import org.mariotaku.twidere.util.support.ViewSupport;
-import org.mariotaku.twidere.view.iface.IExtendedView;
-import org.mariotaku.twidere.view.iface.IExtendedView.TouchInterceptor;
-
-import java.lang.reflect.InvocationTargetException;
-
-import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
-import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
-import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
-
-public class ThemePreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener {
-
- public ThemePreviewPreference(final Context context) {
- this(context, null);
- }
-
- public ThemePreviewPreference(final Context context, final AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ThemePreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
- final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- prefs.registerOnSharedPreferenceChangeListener(this);
- }
-
- @Override
- public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
- if (KEY_THEME.equals(key) || KEY_THEME_BACKGROUND.equals(key) || KEY_THEME_BACKGROUND_ALPHA.equals(key)
- || KEY_THEME_COLOR.equals(key)) {
- notifyChanged();
- }
- }
-
- @Override
- protected View onCreateView(final ViewGroup parent) {
- final Context context = getContext();
- final int themeResource = ThemeUtils.getNoActionBarThemeResource(context);
- final Context theme = new ContextThemeWrapper(context, themeResource);
- final LayoutInflater inflater = LayoutInflater.from(theme);
- try {
- final View view = inflater.inflate(R.layout.theme_preview, parent, false);
- setPreviewView(theme, view.findViewById(R.id.theme_preview_content), themeResource);
- return view;
- } catch (InflateException e) {
- if (e.getCause() instanceof InvocationTargetException) {
- e.getCause().getCause().printStackTrace();
- }
- throw e;
- }
- }
-
- private static void setPreviewView(final Context context, final View view, final int themeRes) {
- if (view instanceof IExtendedView) {
- ((IExtendedView) view).setTouchInterceptor(new DummyTouchInterceptor());
- }
- final View windowBackgroundView = view.findViewById(R.id.theme_preview_window_background);
- final View windowContentOverlayView = view.findViewById(R.id.theme_preview_window_content_overlay);
- final View actionBarOverlay = view.findViewById(R.id.actionbar_overlay);
- final Toolbar actionBarView = (Toolbar) view.findViewById(R.id.action_bar);
- final ActionMenuView menuBar = (ActionMenuView) view.findViewById(R.id.menu_bar);
- final View statusContentView = view.findViewById(R.id.theme_preview_status_content);
- final CardView cardView = (CardView) view.findViewById(R.id.card);
-
- final int defaultTextSize = getDefaultTextSize(context);
- final int cardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context));
- final int accentColor = ThemeUtils.getUserAccentColor(context);
-
- final int themeId = ThemeUtils.getNoActionBarThemeResource(context);
- final String backgroundOption = ThemeUtils.getThemeBackgroundOption(context);
- ThemeUtils.applyWindowBackground(context, windowBackgroundView, themeId, backgroundOption,
- ThemeUtils.getUserThemeBackgroundAlpha(context));
- ViewSupport.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes,
- accentColor, backgroundOption, true));
- ViewCompat.setElevation(actionBarView, ThemeUtils.getSupportActionBarElevation(context));
- ViewSupport.setBackground(actionBarOverlay, ThemeUtils.getWindowContentOverlay(context));
- cardView.setCardBackgroundColor(cardBackgroundColor);
-
- actionBarView.setTitle(R.string.app_name);
- menuBar.setEnabled(false);
- final MenuInflater inflater = new SupportMenuInflater(context);
- inflater.inflate(R.menu.menu_status, menuBar.getMenu());
- ThemeUtils.wrapMenuIcon(menuBar, MENU_GROUP_STATUS_SHARE);
- if (statusContentView != null) {
-
- final View profileView = statusContentView.findViewById(R.id.profile_container);
- final ImageView profileImageView = (ImageView) statusContentView.findViewById(R.id.profile_image);
- final TextView nameView = (TextView) statusContentView.findViewById(R.id.name);
- final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name);
- final TextView textView = (TextView) statusContentView.findViewById(R.id.text);
- final TextView timeSourceView = (TextView) statusContentView.findViewById(R.id.time_source);
- final View retweetedByContainer = statusContentView.findViewById(R.id.retweeted_by_container);
-
- retweetedByContainer.setVisibility(View.GONE);
-
- nameView.setTextSize(defaultTextSize * 1.25f);
- textView.setTextSize(defaultTextSize * 1.25f);
- screenNameView.setTextSize(defaultTextSize * 0.85f);
- timeSourceView.setTextSize(defaultTextSize * 0.85f);
-
- profileView.setBackgroundResource(0);
- textView.setTextIsSelectable(false);
-
- profileImageView.setImageResource(R.mipmap.ic_launcher);
- nameView.setText(TWIDERE_PREVIEW_NAME);
- screenNameView.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
- textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
-
- final String time = formatToLongTimeString(context, System.currentTimeMillis());
- timeSourceView.setText(toPlainText(context.getString(R.string.time_source, time, TWIDERE_PREVIEW_SOURCE)));
- }
- }
-
- private static class DummyTouchInterceptor implements TouchInterceptor {
-
- @Override
- public boolean dispatchTouchEvent(final View view, final MotionEvent event) {
- return false;
- }
-
- @Override
- public boolean onInterceptTouchEvent(final View view, final MotionEvent event) {
- return true;
- }
-
- @Override
- public boolean onTouchEvent(final View view, final MotionEvent event) {
- return false;
- }
-
- }
-
-}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MathUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/MathUtils.java
index 84507935c..91546c98b 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/MathUtils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/MathUtils.java
@@ -46,10 +46,18 @@ public class MathUtils {
}
// Returns the previous power of two.
- // Returns the input if it is already power of 2.
- // Throws IllegalArgumentException if the input is <= 0
- public static int prevPowerOf2(final int n) {
- if (n <= 0) throw new IllegalArgumentException();
- return Integer.highestOneBit(n);
- }
+ // Returns the input if it is already power of 2.
+ // Throws IllegalArgumentException if the input is <= 0
+ public static int prevPowerOf2(final int n) {
+ if (n <= 0) throw new IllegalArgumentException();
+ return Integer.highestOneBit(n);
+ }
+
+ public static double sum(double... doubles) {
+ double sum = 0;
+ for (double d : doubles) {
+ sum += d;
+ }
+ return sum;
+ }
}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
index 3089fa24b..e804520f4 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java
@@ -3823,7 +3823,7 @@ public final class Utils implements Constants {
final SpannableStringBuilder text = SpannableStringBuilder.valueOf(textView.getText());
final URLSpan[] spans = text.getSpans(0, text.length(), URLSpan.class);
URLSpan found = null;
- String findPattern = "twitter.com/" + status.quoted_by_user_screen_name + "/status/" + status.quote_id;
+ String findPattern = "twitter.com/" + status.user_screen_name + "/status/" + status.quote_id;
for (URLSpan span : spans) {
if (span.getURL().contains(findPattern)) {
found = span;
@@ -3920,4 +3920,17 @@ public final class Utils implements Constants {
return location;
}
+ public static final String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
+
+ public static String calculateProperSize(double bytes) {
+ double value = bytes;
+ int index;
+ for (index = 0; index < fileSizeUnits.length; index++) {
+ if (value < 1024) {
+ break;
+ }
+ value = value / 1024;
+ }
+ return String.format("%.2f %s", value, fileSizeUnits[index]);
+ }
}
diff --git a/twidere/src/main/res/layout/layout_preference_network_usage.xml b/twidere/src/main/res/layout/layout_preference_network_usage.xml
new file mode 100644
index 000000000..ef26ba84f
--- /dev/null
+++ b/twidere/src/main/res/layout/layout_preference_network_usage.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/twidere/src/main/res/layout/theme_preview.xml b/twidere/src/main/res/layout/theme_preview.xml
deleted file mode 100644
index b2142d717..000000000
--- a/twidere/src/main/res/layout/theme_preview.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/twidere/src/main/res/layout/theme_preview_content.xml b/twidere/src/main/res/layout/theme_preview_content.xml
deleted file mode 100644
index 23d2cb449..000000000
--- a/twidere/src/main/res/layout/theme_preview_content.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/twidere/src/main/res/layout/theme_preview_status_content.xml b/twidere/src/main/res/layout/theme_preview_status_content.xml
deleted file mode 100644
index c60459b62..000000000
--- a/twidere/src/main/res/layout/theme_preview_status_content.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/twidere/src/main/res/xml/preferences_compose.xml b/twidere/src/main/res/xml/preferences_compose.xml
new file mode 100644
index 000000000..188c5cc6c
--- /dev/null
+++ b/twidere/src/main/res/xml/preferences_compose.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/twidere/src/main/res/xml/preferences_content.xml b/twidere/src/main/res/xml/preferences_content.xml
index 81c5b8a68..33bbd65b1 100644
--- a/twidere/src/main/res/xml/preferences_content.xml
+++ b/twidere/src/main/res/xml/preferences_content.xml
@@ -1,10 +1,12 @@
-
+
+
+
@@ -12,49 +14,20 @@
android:defaultValue=""
android:key="media_uploader"
android:summary="%s"
- android:title="@string/image_uploader"/>
-
-
+ android:title="@string/image_uploader" />
+ android:title="@string/image_preload_options" />
+ android:title="@string/preload_wifi_only" />
-
-
-
-
-
+ app:step="5" />
+ android:title="@string/timeline_sync_service" />
+ android:title="@string/remember_position" />
+ android:title="@string/read_from_bottom" />
+ android:title="@string/trends_location" />
+ android:title="@string/translation_destination" />
+
+
+ android:title="@string/phishing_link_warning" />
+ android:title="@string/display_sensitive_contents" />
\ No newline at end of file
diff --git a/twidere/src/main/res/xml/preferences_interface.xml b/twidere/src/main/res/xml/preferences_interface.xml
deleted file mode 100644
index c081d905f..000000000
--- a/twidere/src/main/res/xml/preferences_interface.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/twidere/src/main/res/xml/preferences_other.xml b/twidere/src/main/res/xml/preferences_other.xml
index 52cbc9625..345e8f07f 100644
--- a/twidere/src/main/res/xml/preferences_other.xml
+++ b/twidere/src/main/res/xml/preferences_other.xml
@@ -1,60 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:value="@xml/preferences_usage_statistics" />
+ android:title="@string/import_export_settings" />
+ android:value="@xml/preferences_scrapyard" />
\ No newline at end of file
diff --git a/twidere/src/main/res/xml/settings_headers.xml b/twidere/src/main/res/xml/settings_headers.xml
index 1990ddc33..28252412c 100644
--- a/twidere/src/main/res/xml/settings_headers.xml
+++ b/twidere/src/main/res/xml/settings_headers.xml
@@ -1,14 +1,14 @@
-
+
+ android:value="@xml/preferences_theme" />
+ android:value="@xml/preferences_cards" />
-
+
+ android:title="@string/tabs" />
-
-
-
+ android:title="@string/extensions" />
+ android:value="@xml/preferences_refresh" />
+ android:value="@xml/preferences_notifications" />
+
+
+
+
+
+ android:value="@xml/preferences_other" />
-
+
+ android:value="@xml/preferences_about" />
+ android:value="file:///android_asset/gpl-3.0-standalone.html" />
\ No newline at end of file