diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java
index e7937bcff..653bf601e 100644
--- a/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/AccountActivity.java
@@ -25,7 +25,6 @@ import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
@@ -50,7 +49,7 @@ import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
-public class AccountActivity extends AppCompatActivity {
+public class AccountActivity extends BaseActivity {
private static final String TAG = "AccountActivity"; // logging tag
private String domain;
diff --git a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java
new file mode 100644
index 000000000..28e523a2f
--- /dev/null
+++ b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java
@@ -0,0 +1,58 @@
+/* Copyright 2017 Andrew Dawson
+ *
+ * This file is part of Tusky.
+ *
+ * Tusky 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.
+ *
+ * Tusky 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 Tusky. If not, see
+ * . */
+
+package com.keylesspalace.tusky;
+
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.TypedValue;
+import android.view.Menu;
+
+/* There isn't presently a way to globally change the theme of a whole application at runtime, just
+ * individual activities. So, each activity has to set its theme before any views are created. And
+ * the most expedient way to accomplish this was to put it in a base class and just have every
+ * activity extend from it. */
+public class BaseActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lightTheme", false)) {
+ setTheme(R.style.AppTheme_Light);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ TypedValue value = new TypedValue();
+ int color;
+ if (getTheme().resolveAttribute(R.attr.toolbar_icon_tint, value, true)) {
+ color = value.data;
+ } else {
+ color = Color.WHITE;
+ }
+ for (int i = 0; i < menu.size(); i++) {
+ Drawable icon = menu.getItem(i).getIcon();
+ if (icon != null) {
+ icon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+ }
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+}
diff --git a/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java b/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
index 6c6d5ae4d..beac9903d 100644
--- a/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/ComposeActivity.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -40,12 +41,12 @@ import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
-import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
+import android.util.TypedValue;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.Button;
@@ -71,18 +72,14 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-public class ComposeActivity extends AppCompatActivity {
+public class ComposeActivity extends BaseActivity {
private static final int STATUS_CHARACTER_LIMIT = 500;
private static final int STATUS_MEDIA_SIZE_LIMIT = 4000000; // 4MB
private static final int MEDIA_PICK_RESULT = 1;
@@ -103,64 +100,28 @@ public class ComposeActivity extends AppCompatActivity {
private View contentWarningBar;
private static class QueuedMedia {
- public enum Type {
+ enum Type {
IMAGE,
VIDEO
}
- public enum ReadyStage {
+ enum ReadyStage {
DOWNSIZING,
UPLOADING,
}
- private Type type;
- private ImageView preview;
- private Uri uri;
- private String id;
- private ReadyStage readyStage;
- private byte[] content;
+ Type type;
+ ImageView preview;
+ Uri uri;
+ String id;
+ ReadyStage readyStage;
+ byte[] content;
- public QueuedMedia(Type type, Uri uri, ImageView preview) {
+ QueuedMedia(Type type, Uri uri, ImageView preview) {
this.type = type;
this.uri = uri;
this.preview = preview;
}
-
- public Type getType() {
- return type;
- }
-
- public ImageView getPreview() {
- return preview;
- }
-
- public Uri getUri() {
- return uri;
- }
-
- public String getId() {
- return id;
- }
-
- public byte[] getContent() {
- return content;
- }
-
- public ReadyStage getReadyStage() {
- return readyStage;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public void setReadyStage(ReadyStage readyStage) {
- this.readyStage = readyStage;
- }
-
- public void setContent(byte[] content) {
- this.content = content;
- }
}
private void doErrorDialog(int descriptionId, int actionId, View.OnClickListener listener) {
@@ -175,10 +136,10 @@ public class ComposeActivity extends AppCompatActivity {
}
private static class FindCharsResult {
- public int charIndex;
- public int stringIndex;
+ int charIndex;
+ int stringIndex;
- public FindCharsResult() {
+ FindCharsResult() {
charIndex = -1;
stringIndex = -1;
}
@@ -281,6 +242,15 @@ public class ComposeActivity extends AppCompatActivity {
}
}
+ private static int getThemeColor(Context context, int attribute) {
+ TypedValue value = new TypedValue();
+ if (context.getTheme().resolveAttribute(attribute, value, true)) {
+ return value.data;
+ } else {
+ return android.R.color.black;
+ }
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -300,7 +270,7 @@ public class ComposeActivity extends AppCompatActivity {
textEditor = (EditText) findViewById(R.id.field_status);
final TextView charactersLeft = (TextView) findViewById(R.id.characters_left);
- final int mentionColour = ContextCompat.getColor(this, R.color.compose_mention);
+ final int mentionColour = getThemeColor(this, R.attr.compose_mention_color);
TextWatcher textEditorWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -414,7 +384,7 @@ public class ComposeActivity extends AppCompatActivity {
}
JSONArray media_ids = new JSONArray();
for (QueuedMedia item : mediaQueued) {
- media_ids.put(item.getId());
+ media_ids.put(item.id);
}
if (media_ids.length() > 0) {
parameters.put("media_ids", media_ids);
@@ -429,12 +399,13 @@ public class ComposeActivity extends AppCompatActivity {
public void onResponse(JSONObject response) {
onSendSuccess();
}
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- onSendFailure();
- }
- }) {
+ },
+ new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ onSendFailure();
+ }
+ }) {
@Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap<>();
@@ -454,8 +425,8 @@ public class ComposeActivity extends AppCompatActivity {
textEditor.setError(getString(R.string.error_sending_status));
}
- private void readyStatus(final String content, final String visibility,
- final boolean sensitive, final String spoilerText) {
+ private void readyStatus(final String content, final String visibility, final boolean sensitive,
+ final String spoilerText) {
final ProgressDialog dialog = ProgressDialog.show(
this, getString(R.string.dialog_title_finishing_media_upload),
getString(R.string.dialog_message_uploading_media), true, true);
@@ -570,7 +541,7 @@ public class ComposeActivity extends AppCompatActivity {
private void addMediaToQueue(QueuedMedia.Type type, Bitmap preview, Uri uri, long mediaSize) {
final QueuedMedia item = new QueuedMedia(type, uri, new ImageView(this));
- ImageView view = item.getPreview();
+ ImageView view = item.preview;
Resources resources = getResources();
int side = resources.getDimensionPixelSize(R.dimen.compose_media_preview_side);
int margin = resources.getDimensionPixelSize(R.dimen.compose_media_preview_margin);
@@ -598,7 +569,7 @@ public class ComposeActivity extends AppCompatActivity {
textEditor.setPadding(textEditor.getPaddingLeft(), textEditor.getPaddingTop(),
textEditor.getPaddingRight(), totalHeight);
// If there's one video in the queue it is full, so disable the button to queue more.
- if (item.getType() == QueuedMedia.Type.VIDEO) {
+ if (item.type == QueuedMedia.Type.VIDEO) {
disableMediaPicking();
}
} else if (queuedCount >= Status.MAX_MEDIA_ATTACHMENTS) {
@@ -617,7 +588,7 @@ public class ComposeActivity extends AppCompatActivity {
}
private void removeMediaFromQueue(QueuedMedia item) {
- mediaPreviewBar.removeView(item.getPreview());
+ mediaPreviewBar.removeView(item.preview);
mediaQueued.remove(item);
if (mediaQueued.size() == 0) {
showMarkSensitive(false);
@@ -639,10 +610,10 @@ public class ComposeActivity extends AppCompatActivity {
}
private void downsizeMedia(final QueuedMedia item) {
- item.setReadyStage(QueuedMedia.ReadyStage.DOWNSIZING);
+ item.readyStage = QueuedMedia.ReadyStage.DOWNSIZING;
InputStream stream;
try {
- stream = getContentResolver().openInputStream(item.getUri());
+ stream = getContentResolver().openInputStream(item.uri);
} catch (FileNotFoundException e) {
onMediaDownsizeFailure(item);
return;
@@ -652,7 +623,7 @@ public class ComposeActivity extends AppCompatActivity {
new DownsizeImageTask(STATUS_MEDIA_SIZE_LIMIT, new DownsizeImageTask.Listener() {
@Override
public void onSuccess(List contentList) {
- item.setContent(contentList.get(0));
+ item.content = contentList.get(0);
uploadMedia(item);
}
@@ -695,7 +666,7 @@ public class ComposeActivity extends AppCompatActivity {
}
private void uploadMedia(final QueuedMedia item) {
- item.setReadyStage(QueuedMedia.ReadyStage.UPLOADING);
+ item.readyStage = QueuedMedia.ReadyStage.UPLOADING;
String endpoint = getString(R.string.endpoint_media);
String url = "https://" + domain + endpoint;
@@ -714,7 +685,7 @@ public class ComposeActivity extends AppCompatActivity {
@Override
public void onResponse(JSONObject response) {
try {
- item.setId(response.getString("id"));
+ item.id = response.getString("id");
} catch (JSONException e) {
onUploadFailure(item);
return;
@@ -736,11 +707,11 @@ public class ComposeActivity extends AppCompatActivity {
@Override
public DataItem getData() {
- byte[] content = item.getContent();
+ byte[] content = item.content;
if (content == null) {
InputStream stream;
try {
- stream = getContentResolver().openInputStream(item.getUri());
+ stream = getContentResolver().openInputStream(item.uri);
} catch (FileNotFoundException e) {
return null;
}
@@ -758,7 +729,7 @@ public class ComposeActivity extends AppCompatActivity {
return data;
}
};
- request.addMarker("media_" + item.getUri().toString());
+ request.addMarker("media_" + item.uri.toString());
VolleySingleton.getInstance(this).addToRequestQueue(request);
}
@@ -768,8 +739,8 @@ public class ComposeActivity extends AppCompatActivity {
}
private void cancelReadyingMedia(QueuedMedia item) {
- if (item.getReadyStage() == QueuedMedia.ReadyStage.UPLOADING) {
- VolleySingleton.getInstance(this).cancelRequest("media_" + item.getUri().toString());
+ if (item.readyStage == QueuedMedia.ReadyStage.UPLOADING) {
+ VolleySingleton.getInstance(this).cancelRequest("media_" + item.uri.toString());
}
waitForMediaLatch.countDown();
}
@@ -799,7 +770,7 @@ public class ComposeActivity extends AppCompatActivity {
return;
}
if (mediaQueued.size() > 0
- && mediaQueued.get(0).getType() == QueuedMedia.Type.IMAGE) {
+ && mediaQueued.get(0).type == QueuedMedia.Type.IMAGE) {
displayTransientError(R.string.error_media_upload_image_or_video);
return;
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/LoginActivity.java b/app/src/main/java/com/keylesspalace/tusky/LoginActivity.java
index 4f80550b6..582cdf9cb 100644
--- a/app/src/main/java/com/keylesspalace/tusky/LoginActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/LoginActivity.java
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
@@ -42,7 +41,7 @@ import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
-public class LoginActivity extends AppCompatActivity {
+public class LoginActivity extends BaseActivity {
private static final String TAG = "LoginActivity";
private static String OAUTH_SCOPES = "read write follow";
@@ -279,7 +278,7 @@ public class LoginActivity extends AppCompatActivity {
errorText.setText(error);
} else {
// This case means a junk response was received somehow.
- errorText.setText("An unidentified authorization error occurred.");
+ errorText.setText(getString(R.string.error_authorization_unknown));
}
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
index b74a62478..317e3a97f 100644
--- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.java
@@ -24,10 +24,8 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
-import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
-import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
@@ -43,7 +41,7 @@ import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
-public class MainActivity extends AppCompatActivity {
+public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity"; // logging tag
private AlarmManager alarmManager;
@@ -102,20 +100,6 @@ public class MainActivity extends AppCompatActivity {
} else {
alarmManager.cancel(serviceAlarmIntent);
}
-
- /* @Unused: for Firebase Push Notifications
- Log.d(TAG, "token " + FirebaseInstanceId.getInstance().getToken());
-
- // Check if it's necessary to register for push notifications for this instance.
- boolean registered = preferences.getBoolean("firebaseRegistered", false);
- if (!registered) {
- String registrationId = preferences.getString("firebaseRegistrationId", null);
- if (registrationId == null) {
- registrationId = FirebaseInstanceId.getInstance().getToken();
- }
- sendRegistrationToServer(registrationId, true);
- }
- */
}
private void fetchUserInfo() {
@@ -180,71 +164,6 @@ public class MainActivity extends AppCompatActivity {
Log.e(TAG, "Failed to fetch user info. " + exception.getMessage());
}
- /* @Unused: For Firebase push notifications, useless for now.
- private void sendRegistrationToServer(String token, final boolean register) {
- SharedPreferences preferences = getSharedPreferences(
- getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
- String domain = preferences.getString("domain", null);
- final String accessToken = preferences.getString("accessToken", null);
-
- String endpoint;
- if (register) {
- endpoint = getString(R.string.endpoint_devices_register);
- } else {
- endpoint = getString(R.string.endpoint_devices_unregister);
- }
- String url = "https://" + domain + endpoint;
- JSONObject formData = new JSONObject();
- try {
- formData.put("registration_id", token);
- } catch (JSONException e) {
- onSendRegistrationToServerFailure();
- return;
- }
- JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, formData,
- new Response.Listener() {
- @Override
- public void onResponse(JSONObject response) {
- onSendRegistrationToServerSuccess(response, register);
- }
- },
- new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- onSendRegistrationToServerFailure();
- }
- }) {
- @Override
- public Map getHeaders() throws AuthFailureError {
- Map headers = new HashMap<>();
- headers.put("Authorization", "Bearer " + accessToken);
- return headers;
- }
- };
- VolleySingleton.getInstance(this).addToRequestQueue(request);
- }
-
- private void onSendRegistrationToServerSuccess(JSONObject response, boolean register) {
- String registeredWord;
- if (register) {
- registeredWord = "registration";
- } else {
- registeredWord = "unregistration";
- }
- Log.d(TAG, String.format("Firebase %s is confirmed with the Mastodon instance. %s",
- registeredWord, response.toString()));
- SharedPreferences preferences = getSharedPreferences(
- getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = preferences.edit();
- editor.putBoolean("firebaseRegistered", register);
- editor.apply();
- }
-
- private void onSendRegistrationToServerFailure() {
- Log.d(TAG, "Firebase registration with the Mastodon instance failed");
- }
- */
-
private void compose() {
Intent intent = new Intent(this, ComposeActivity.class);
startActivity(intent);
diff --git a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.java b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.java
index f09c6d23e..22187c716 100644
--- a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.java
@@ -15,16 +15,79 @@
package com.keylesspalace.tusky;
+import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
-public class PreferencesActivity extends AppCompatActivity {
+public class PreferencesActivity extends AppCompatActivity
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private boolean themeSwitched;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ themeSwitched = savedInstanceState.getBoolean("themeSwitched");
+ } else {
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ themeSwitched = extras.getBoolean("themeSwitched");
+ } else {
+ themeSwitched = false;
+ }
+ }
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ if (preferences.getBoolean("lightTheme", false)) {
+ setTheme(R.style.AppTheme_Light);
+ }
+ preferences.registerOnSharedPreferenceChangeListener(this);
+
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PreferencesFragment())
.commit();
}
+
+ private void saveInstanceState(Bundle outState) {
+ outState.putBoolean("themeSwitched", themeSwitched);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ saveInstanceState(outState);
+ super.onSaveInstanceState(outState);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals("lightTheme")) {
+ themeSwitched = true;
+ // recreate() could be used instead, but it doesn't have an animation B).
+ Intent intent = getIntent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ Bundle savedInstanceState = new Bundle();
+ saveInstanceState(savedInstanceState);
+ intent.putExtras(savedInstanceState);
+ startActivity(intent);
+ finish();
+ overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ /* Switching themes won't actually change the theme of activities on the back stack.
+ * Either the back stack activities need to all be recreated, or do the easier thing, which
+ * is hijack the back button press and use it to launch a new MainActivity and clear the
+ * back stack. */
+ if (themeSwitched) {
+ Intent intent = new Intent(this, MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ } else {
+ super.onBackPressed();
+ }
+ }
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.java b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.java
index 107f25b3c..1297196c6 100644
--- a/app/src/main/java/com/keylesspalace/tusky/SplashActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/SplashActivity.java
@@ -20,7 +20,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.support.v7.app.AppCompatDelegate;
public class SplashActivity extends AppCompatActivity {
@Override
diff --git a/app/src/main/java/com/keylesspalace/tusky/Status.java b/app/src/main/java/com/keylesspalace/tusky/Status.java
index ecfe2704e..6d018b3f3 100644
--- a/app/src/main/java/com/keylesspalace/tusky/Status.java
+++ b/app/src/main/java/com/keylesspalace/tusky/Status.java
@@ -43,7 +43,7 @@ public class Status {
private Spanned content;
/** the fully-qualified url of the avatar image */
private String avatar;
- private String rebloggedByUsername;
+ private String rebloggedByDisplayName;
/** when the status was initially created */
private Date createdAt;
/** whether the authenticated user has reblogged this status */
@@ -104,8 +104,8 @@ public class Status {
return createdAt;
}
- public String getRebloggedByUsername() {
- return rebloggedByUsername;
+ public String getRebloggedByDisplayName() {
+ return rebloggedByDisplayName;
}
public boolean getReblogged() {
@@ -136,8 +136,8 @@ public class Status {
return mentions;
}
- public void setRebloggedByUsername(String name) {
- rebloggedByUsername = name;
+ public void setRebloggedByDisplayName(String name) {
+ rebloggedByDisplayName = name;
}
public void setReblogged(boolean reblogged) {
@@ -257,7 +257,7 @@ public class Status {
Status status;
if (reblog != null) {
status = reblog;
- status.setRebloggedByUsername(username);
+ status.setRebloggedByDisplayName(displayName);
} else {
Spanned contentPlus = HtmlUtils.fromHtml(content);
status = new Status(
diff --git a/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java
index 7383214f4..bfccc1f76 100644
--- a/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java
+++ b/app/src/main/java/com/keylesspalace/tusky/StatusViewHolder.java
@@ -26,7 +26,6 @@ import android.text.style.URLSpan;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageButton;
-import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;
@@ -43,7 +42,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
private TextView content;
private NetworkImageView avatar;
private View rebloggedBar;
- private TextView rebloggedByUsername;
+ private TextView rebloggedByDisplayName;
private ImageButton replyButton;
private StatusButton reblogButton;
private StatusButton favouriteButton;
@@ -70,7 +69,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
avatar.setDefaultImageResId(R.drawable.avatar_default);
avatar.setErrorImageResId(R.drawable.avatar_error);
rebloggedBar = itemView.findViewById(R.id.status_reblogged_bar);
- rebloggedByUsername = (TextView) itemView.findViewById(R.id.status_reblogged);
+ rebloggedByDisplayName = (TextView) itemView.findViewById(R.id.status_reblogged);
replyButton = (ImageButton) itemView.findViewById(R.id.status_reply);
reblogButton = (StatusButton) itemView.findViewById(R.id.status_reblog);
favouriteButton = (StatusButton) itemView.findViewById(R.id.status_favourite);
@@ -174,15 +173,15 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
sinceCreated.setText(readout);
}
- public void setRebloggedByUsername(String name) {
- Context context = rebloggedByUsername.getContext();
+ public void setRebloggedByDisplayName(String name) {
+ Context context = rebloggedByDisplayName.getContext();
String format = context.getString(R.string.status_boosted_format);
String boostedText = String.format(format, name);
- rebloggedByUsername.setText(boostedText);
+ rebloggedByDisplayName.setText(boostedText);
rebloggedBar.setVisibility(View.VISIBLE);
}
- public void hideRebloggedByUsername() {
+ public void hideRebloggedByDisplayName() {
rebloggedBar.setVisibility(View.GONE);
}
@@ -332,11 +331,11 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
setAvatar(status.getAvatar());
setReblogged(status.getReblogged());
setFavourited(status.getFavourited());
- String rebloggedByUsername = status.getRebloggedByUsername();
- if (rebloggedByUsername == null) {
- hideRebloggedByUsername();
+ String rebloggedByDisplayName = status.getRebloggedByDisplayName();
+ if (rebloggedByDisplayName == null) {
+ hideRebloggedByDisplayName();
} else {
- setRebloggedByUsername(rebloggedByUsername);
+ setRebloggedByDisplayName(rebloggedByDisplayName);
}
Status.MediaAttachment[] attachments = status.getAttachments();
boolean sensitive = status.getSensitive();
diff --git a/app/src/main/java/com/keylesspalace/tusky/ViewTagActivity.java b/app/src/main/java/com/keylesspalace/tusky/ViewTagActivity.java
index dd3c26e88..39dcef2fc 100644
--- a/app/src/main/java/com/keylesspalace/tusky/ViewTagActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/ViewTagActivity.java
@@ -20,10 +20,9 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-public class ViewTagActivity extends AppCompatActivity {
+public class ViewTagActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/keylesspalace/tusky/ViewThreadActivity.java b/app/src/main/java/com/keylesspalace/tusky/ViewThreadActivity.java
index c6e31a8e0..3250d50e0 100644
--- a/app/src/main/java/com/keylesspalace/tusky/ViewThreadActivity.java
+++ b/app/src/main/java/com/keylesspalace/tusky/ViewThreadActivity.java
@@ -21,13 +21,11 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
-public class ViewThreadActivity extends AppCompatActivity {
-
+public class ViewThreadActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml
new file mode 100644
index 000000000..972e757ec
--- /dev/null
+++ b/app/src/main/res/anim/fade_in.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml
new file mode 100644
index 000000000..9b48ae8f6
--- /dev/null
+++ b/app/src/main/res/anim/fade_out.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/favourite_button_light.xml b/app/src/main/res/color/favourite_button_light.xml
new file mode 100644
index 000000000..c9511a3c1
--- /dev/null
+++ b/app/src/main/res/color/favourite_button_light.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/media_button_light.xml b/app/src/main/res/color/media_button_light.xml
new file mode 100644
index 000000000..73da3f031
--- /dev/null
+++ b/app/src/main/res/color/media_button_light.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/reblog_button_light.xml b/app/src/main/res/color/reblog_button_light.xml
new file mode 100644
index 000000000..a2fb223c3
--- /dev/null
+++ b/app/src/main/res/color/reblog_button_light.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/media_preview_unloaded.xml b/app/src/main/res/drawable/media_preview_unloaded.xml
index 76a1e531e..9ff8a8d1a 100644
--- a/app/src/main/res/drawable/media_preview_unloaded.xml
+++ b/app/src/main/res/drawable/media_preview_unloaded.xml
@@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
-
+
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/toggle_small_light.xml b/app/src/main/res/drawable/toggle_small_light.xml
new file mode 100644
index 000000000..6f317d601
--- /dev/null
+++ b/app/src/main/res/drawable/toggle_small_light.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml
index 02f73c956..e99535c8a 100644
--- a/app/src/main/res/layout/activity_account.xml
+++ b/app/src/main/res/layout/activity_account.xml
@@ -79,7 +79,7 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="@color/colorPrimary"
+ android:background="?attr/toolbar_background_color"
android:layout_gravity="top"
app:layout_collapseMode="pin" />
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index b913af609..124130cb8 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -10,8 +10,8 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="@color/colorPrimary"
- android:elevation="4dp" />
+ android:elevation="4dp"
+ android:background="?attr/toolbar_background_color" />
+ android:elevation="4dp"
+ android:background="?attr/toolbar_background_color" />
+ android:elevation="4dp"
+ android:background="?attr/toolbar_background_color" />
+ android:elevation="4dp"
+ android:background="?attr/toolbar_background_color" />
+ android:paddingLeft="@dimen/status_reblogged_icon_left_padding"
+ android:tint="?attr/notification_icon_tint" />
@@ -182,6 +183,7 @@
android:layout_height="@dimen/status_media_preview_height"
android:layout_weight="1"
android:scaleType="centerCrop" />
+
@@ -198,9 +200,9 @@
+ android:layout_height="32dp"
+ style="?attr/image_button_style" />
@@ -222,7 +224,7 @@
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index bc4c8a520..80ccdde14 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -11,16 +11,21 @@
+
+
-
-
+
+
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 003920a1f..dfa06414e 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,21 +1,58 @@
- #44A673
- #2C996E
- #3F8A65
- #3C4945
- #191E1E
+
#4F4F4F
- #3F8A65
- #CFCFCF
#000000
- #303030
- #2F2F2F
- #AFBFCF
- #9F9F9F
- #CFCFCF
+
+ #44A673
+ #2C996E
+ #3F8A65
+ #3F8A65
+ #3C4945
+ #191E1E
+ #FFFFFF
+ #FFFFFF
+ #FFFFFF
+ #FFFFFF
+ #000000
+ #000000
+ #000000
+ #44A673
+ #FFFFFF
+ #CFCFCF
+ #303030
+ #2F2F2F
#A4B4BC
#000000
#4C534B
#000000
+ #AFBFCF
+ #9F9F9F
+ #CFCFCF
+
+ #44A673
+ #2C996E
+ #3F8A65
+ #79daa8
+ #FFFFFF
+ #FFFFFF
+ #000000
+ #000000
+ #000000
+ #000000
+ #FFFFFF
+ #FFFFFF
+ #FFFFFF
+ #f6f7f7
+ #000000
+ #2F2F2F
+ #B0B0B0
+ #CFCFCF
+ #34444C
+ #CFCFCF
+ #9F9F9F
+ #EFEFEF
+ #2F5F6F
+ #7F7F7F
+ #1F1F1F
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 83220dc63..0f82b3bad 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -41,6 +41,7 @@
/api/v1/devices/register
/api/v1/devices/unregister
+ An unidentified authorization error occurred.
Notifications could not be fetched.
The status is too long!
The status failed to be sent.
@@ -135,5 +136,7 @@
Notify with a sound
Notify with vibration
Notify with light
+ Appearance
+ Use The Light Theme
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 77bb23755..8971cfb0a 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,56 +1,117 @@
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index e2b7f4172..9cedad582 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -2,8 +2,7 @@
-
+
+
+
+
+
+
+