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 @@ - + + + + + + +