diff --git a/build.gradle b/build.gradle index 19ac98b6b..48c74ccfe 100644 --- a/build.gradle +++ b/build.gradle @@ -169,6 +169,8 @@ android { minSdkVersion 9 targetSdkVersion 22 + vectorDrawables.useSupportLibrary = true + buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L" buildConfigField "String", "TEXTSECURE_URL", "\"https://textsecure-service.whispersystems.org\"" buildConfigField "String", "GIPHY_PROXY_HOST", "\"giphy-proxy-production.whispersystems.org\"" diff --git a/res/animator/bottom_pause_to_play_animation.xml b/res/animator/bottom_pause_to_play_animation.xml new file mode 100644 index 000000000..f5b474bb7 --- /dev/null +++ b/res/animator/bottom_pause_to_play_animation.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/res/animator/bottom_play_to_pause_animation.xml b/res/animator/bottom_play_to_pause_animation.xml new file mode 100644 index 000000000..4f2778d68 --- /dev/null +++ b/res/animator/bottom_play_to_pause_animation.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/res/animator/rotate_90_animation.xml b/res/animator/rotate_90_animation.xml new file mode 100644 index 000000000..7d44ce690 --- /dev/null +++ b/res/animator/rotate_90_animation.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/res/animator/rotate_minus_90_animation.xml b/res/animator/rotate_minus_90_animation.xml new file mode 100644 index 000000000..ef9e1b6f1 --- /dev/null +++ b/res/animator/rotate_minus_90_animation.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/res/animator/upper_pause_to_play_animation.xml b/res/animator/upper_pause_to_play_animation.xml new file mode 100644 index 000000000..880c7b0b8 --- /dev/null +++ b/res/animator/upper_pause_to_play_animation.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/res/animator/upper_play_to_pause_animation.xml b/res/animator/upper_play_to_pause_animation.xml new file mode 100644 index 000000000..ffa933231 --- /dev/null +++ b/res/animator/upper_play_to_pause_animation.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/res/drawable-hdpi/ic_circle_fill_white_48dp.png b/res/drawable-hdpi/ic_circle_fill_white_48dp.png new file mode 100644 index 000000000..a417946f2 Binary files /dev/null and b/res/drawable-hdpi/ic_circle_fill_white_48dp.png differ diff --git a/res/drawable-mdpi/ic_circle_fill_white_48dp.png b/res/drawable-mdpi/ic_circle_fill_white_48dp.png new file mode 100644 index 000000000..783f82cf1 Binary files /dev/null and b/res/drawable-mdpi/ic_circle_fill_white_48dp.png differ diff --git a/res/drawable-xhdpi/ic_circle_fill_white_48dp.png b/res/drawable-xhdpi/ic_circle_fill_white_48dp.png new file mode 100644 index 000000000..0bd968386 Binary files /dev/null and b/res/drawable-xhdpi/ic_circle_fill_white_48dp.png differ diff --git a/res/drawable-xxhdpi/ic_circle_fill_white_48dp.png b/res/drawable-xxhdpi/ic_circle_fill_white_48dp.png new file mode 100644 index 000000000..c83d5fba1 Binary files /dev/null and b/res/drawable-xxhdpi/ic_circle_fill_white_48dp.png differ diff --git a/res/drawable-xxxhdpi/ic_circle_fill_white_48dp.png b/res/drawable-xxxhdpi/ic_circle_fill_white_48dp.png new file mode 100644 index 000000000..b6b9ab51b Binary files /dev/null and b/res/drawable-xxxhdpi/ic_circle_fill_white_48dp.png differ diff --git a/res/drawable/pause_icon.xml b/res/drawable/pause_icon.xml new file mode 100644 index 000000000..e7f9fce53 --- /dev/null +++ b/res/drawable/pause_icon.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/pause_to_play_animation.xml b/res/drawable/pause_to_play_animation.xml new file mode 100644 index 000000000..4d19dc4f9 --- /dev/null +++ b/res/drawable/pause_to_play_animation.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/play_icon.xml b/res/drawable/play_icon.xml new file mode 100644 index 000000000..7472ac7de --- /dev/null +++ b/res/drawable/play_icon.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/play_to_pause_animation.xml b/res/drawable/play_to_pause_animation.xml new file mode 100644 index 000000000..b8bc7934f --- /dev/null +++ b/res/drawable/play_to_pause_animation.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/layout/audio_view.xml b/res/layout/audio_view.xml index 1ad457fd1..dd3dff543 100644 --- a/res/layout/audio_view.xml +++ b/res/layout/audio_view.xml @@ -28,7 +28,7 @@ app:matProg_barColor="@color/white" app:matProg_linearProgress="true" app:matProg_spinSpeed="0.333" - tools:visibility="visible"/> + tools:visibility="gone"/> + app:foregroundTintColor="@color/grey_500" + app:backgroundTintColor="@color/white"/> diff --git a/res/layout/conversation_item_received.xml b/res/layout/conversation_item_received.xml index 4a15fa8de..6d45ef9fd 100644 --- a/res/layout/conversation_item_received.xml +++ b/res/layout/conversation_item_received.xml @@ -65,7 +65,8 @@ android:layout_width="210dp" android:layout_height="wrap_content" android:visibility="gone" - app:tintColor="@color/white" + app:foregroundTintColor="@color/white" + app:backgroundTintColor="@color/blue_500" tools:visibility="visible"/> - + + diff --git a/res/values/integers.xml b/res/values/integers.xml new file mode 100644 index 000000000..bb4c483c9 --- /dev/null +++ b/res/values/integers.xml @@ -0,0 +1,4 @@ + + + 300 + \ No newline at end of file diff --git a/res/values/vector_paths.xml b/res/values/vector_paths.xml new file mode 100644 index 000000000..d4f9bb2ec --- /dev/null +++ b/res/values/vector_paths.xml @@ -0,0 +1,20 @@ + + + + M 44 32 L 44 64 L 100 64 L 100 64 Z + M 44 96 L 44 64 L 100 64 L 100 64 Z + + + M 32 40 L 32 56 L 96 56 L 96 40 Z + M 32 88 L 32 72 L 96 72 L 96 88 Z + + + upperpart + bottompart + parts + + + upper + bottom + + \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index 1c4e902bb..a228331c1 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -231,21 +231,24 @@ public class ConversationItem extends LinearLayout if (messageRecord.isOutgoing()) { bodyBubble.getBackground().setColorFilter(defaultBubbleColor, PorterDuff.Mode.MULTIPLY); mediaThumbnail.setBackgroundColorHint(defaultBubbleColor); - setAudioViewTint(messageRecord, conversationRecipients); } else { int color = recipient.getColor().toConversationColor(context); bodyBubble.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY); mediaThumbnail.setBackgroundColorHint(color); } + + setAudioViewTint(messageRecord, conversationRecipients); } private void setAudioViewTint(MessageRecord messageRecord, Recipients recipients) { if (messageRecord.isOutgoing()) { if (DynamicTheme.LIGHT.equals(TextSecurePreferences.getTheme(context))) { - audioView.setTint(recipients.getColor().toConversationColor(context)); + audioView.setTint(recipients.getColor().toConversationColor(context), defaultBubbleColor); } else { - audioView.setTint(Color.WHITE); + audioView.setTint(Color.WHITE, defaultBubbleColor); } + } else { + audioView.setTint(Color.WHITE, recipients.getColor().toConversationColor(context)); } } diff --git a/src/org/thoughtcrime/securesms/components/AudioView.java b/src/org/thoughtcrime/securesms/components/AudioView.java index 041cd15c9..ee9c024e7 100644 --- a/src/org/thoughtcrime/securesms/components/AudioView.java +++ b/src/org/thoughtcrime/securesms/components/AudioView.java @@ -1,9 +1,12 @@ package org.thoughtcrime.securesms.components; +import android.annotation.TargetApi; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PorterDuff; +import android.graphics.drawable.AnimatedVectorDrawable; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -71,9 +74,17 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener this.pauseButton.setOnClickListener(new PauseClickedListener()); this.seekBar.setOnSeekBarChangeListener(new SeekBarModifiedListener()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + this.playButton.setImageDrawable(context.getDrawable(R.drawable.play_icon)); + this.pauseButton.setImageDrawable(context.getDrawable(R.drawable.pause_icon)); + this.playButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp)); + this.pauseButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp)); + } + if (attrs != null) { TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AudioView, 0, 0); - setTint(typedArray.getColor(R.styleable.AudioView_tintColor, Color.WHITE)); + setTint(typedArray.getColor(R.styleable.AudioView_foregroundTintColor, Color.WHITE), + typedArray.getColor(R.styleable.AudioView_backgroundTintColor, Color.WHITE)); typedArray.recycle(); } } @@ -125,12 +136,16 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener @Override public void onStart() { - this.controlToggle.display(this.pauseButton); + if (this.pauseButton.getVisibility() != View.VISIBLE) { + togglePlayToPause(); + } } @Override public void onStop() { - this.controlToggle.display(this.playButton); + if (this.playButton.getVisibility() != View.VISIBLE) { + togglePauseToPlay(); + } if (seekBar.getProgress() + 5 >= seekBar.getMax()) { backwardsCounter = 4; @@ -153,17 +168,25 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener } } - public void setTint(int tint) { - this.playButton.setColorFilter(tint, PorterDuff.Mode.SRC_IN); - this.pauseButton.setColorFilter(tint, PorterDuff.Mode.SRC_IN); - this.downloadButton.setColorFilter(tint, PorterDuff.Mode.SRC_IN); - this.downloadProgress.setBarColor(tint); + public void setTint(int foregroundTint, int backgroundTint) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + this.playButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint)); + this.playButton.setImageTintList(ColorStateList.valueOf(backgroundTint)); + this.pauseButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint)); + this.pauseButton.setImageTintList(ColorStateList.valueOf(backgroundTint)); + } else { + this.playButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); + this.pauseButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); + } - this.timestamp.setTextColor(tint); - this.seekBar.getProgressDrawable().setColorFilter(tint, PorterDuff.Mode.SRC_IN); + this.downloadButton.setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); + this.downloadProgress.setBarColor(foregroundTint); + + this.timestamp.setTextColor(foregroundTint); + this.seekBar.getProgressDrawable().setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - this.seekBar.getThumb().setColorFilter(tint, PorterDuff.Mode.SRC_IN); + this.seekBar.getThumb().setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN); } } @@ -175,13 +198,34 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener } } + private void togglePlayToPause() { + controlToggle.displayQuick(pauseButton); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AnimatedVectorDrawable playToPauseDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.play_to_pause_animation); + pauseButton.setImageDrawable(playToPauseDrawable); + playToPauseDrawable.start(); + } + } + + private void togglePauseToPlay() { + controlToggle.displayQuick(playButton); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AnimatedVectorDrawable pauseToPlayDrawable = (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.pause_to_play_animation); + playButton.setImageDrawable(pauseToPlayDrawable); + pauseToPlayDrawable.start(); + } + } + private class PlayClickedListener implements View.OnClickListener { + @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onClick(View v) { try { Log.w(TAG, "playbutton onClick"); if (audioSlidePlayer != null) { - controlToggle.display(pauseButton); + togglePlayToPause(); audioSlidePlayer.play(getProgress()); } } catch (IOException e) { @@ -191,11 +235,12 @@ public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener } private class PauseClickedListener implements View.OnClickListener { + @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onClick(View v) { Log.w(TAG, "pausebutton onClick"); if (audioSlidePlayer != null) { - controlToggle.display(playButton); + togglePauseToPlay(); audioSlidePlayer.stop(); } } diff --git a/src/org/thoughtcrime/securesms/components/InputPanel.java b/src/org/thoughtcrime/securesms/components/InputPanel.java index 9e8e98ca9..1067a0508 100644 --- a/src/org/thoughtcrime/securesms/components/InputPanel.java +++ b/src/org/thoughtcrime/securesms/components/InputPanel.java @@ -80,10 +80,10 @@ public class InputPanel extends LinearLayout this.microphoneRecorderView = ViewUtil.findById(this, R.id.recorder_view); this.microphoneRecorderView.setListener(this); -// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { this.microphoneRecorderView.setVisibility(View.GONE); this.microphoneRecorderView.setClickable(false); -// } + } if (TextSecurePreferences.isSystemEmojiPreferred(getContext())) { emojiToggle.setVisibility(View.GONE);