Added new media icons for audio/video
Added icons new icons, deleted an old one. Using new icons in AudioSlide/VideoSlide. Closes #2304
12
BUILDING.md
@ -30,6 +30,18 @@ The following steps should help you (re)build TextSecure from the command line.
|
||||
|
||||
./gradlew build
|
||||
|
||||
Visual assets
|
||||
----------------------
|
||||
|
||||
Source assets tend to be large binary blobs, which are best stored outside of git repositories. We host ours in a [Pixelapse repository](https://www.pixelapse.com/openwhispersystems/projects/signal-android/). Some source files are SVGs that can be auto-colored and sized using a tool like [android-res-utils](https://github.com/sebkur/android-res-utils).
|
||||
|
||||
Sample command for generating our audio placeholder image:
|
||||
|
||||
```bash
|
||||
pngs_from_svg.py ic_audio.svg /path/to/TextSecure/res/ 150 "#000" 0.54 _light
|
||||
pngs_from_svg.py ic_audio.svg /path/to/TextSecure/res/ 150 "#fff" 1.0 _dark
|
||||
```
|
||||
|
||||
Setting up a development environment
|
||||
------------------------------------
|
||||
|
||||
|
BIN
res/drawable-hdpi/ic_audio_dark.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
res/drawable-hdpi/ic_audio_light.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
res/drawable-hdpi/ic_video_dark.png
Normal file
After Width: | Height: | Size: 941 B |
BIN
res/drawable-hdpi/ic_video_light.png
Normal file
After Width: | Height: | Size: 862 B |
BIN
res/drawable-mdpi/ic_audio_dark.png
Normal file
After Width: | Height: | Size: 1023 B |
BIN
res/drawable-mdpi/ic_audio_light.png
Normal file
After Width: | Height: | Size: 888 B |
BIN
res/drawable-mdpi/ic_video_dark.png
Normal file
After Width: | Height: | Size: 596 B |
BIN
res/drawable-mdpi/ic_video_light.png
Normal file
After Width: | Height: | Size: 542 B |
BIN
res/drawable-xhdpi/ic_audio_dark.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
res/drawable-xhdpi/ic_audio_light.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
res/drawable-xhdpi/ic_video_dark.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-xhdpi/ic_video_light.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-xxhdpi/ic_audio_dark.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
res/drawable-xxhdpi/ic_audio_light.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
res/drawable-xxhdpi/ic_video_dark.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
res/drawable-xxhdpi/ic_video_light.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.7 KiB |
@ -51,6 +51,9 @@
|
||||
<attr name="conversation_item_sent_push_pending_background" format="reference" />
|
||||
<attr name="conversation_item_sent_push_pending_triangle_background" format="reference" />
|
||||
|
||||
<attr name="conversation_icon_attach_audio" format="reference"/>
|
||||
<attr name="conversation_icon_attach_video" format="reference" />
|
||||
|
||||
<attr name="contact_selection_push_user" format="reference|color" />
|
||||
<attr name="contact_selection_lay_user" format="reference|color" />
|
||||
<attr name="contact_selection_label_text" format="reference|color" />
|
||||
|
@ -94,6 +94,9 @@
|
||||
<item name="menu_forward_icon">@drawable/ic_forward_white_24dp</item>
|
||||
<item name="menu_save_icon">@drawable/ic_save_white_24dp</item>
|
||||
|
||||
<item name="conversation_icon_attach_audio">@drawable/ic_audio_light</item>
|
||||
<item name="conversation_icon_attach_video">@drawable/ic_video_light</item>
|
||||
|
||||
<item name="reminder_header_background">#ff1d85d7</item>
|
||||
|
||||
<item name="pref_ic_push">@drawable/ic_push_black</item>
|
||||
@ -193,6 +196,9 @@
|
||||
<item name="menu_forward_icon">@drawable/ic_forward_white_24dp</item>
|
||||
<item name="menu_save_icon">@drawable/ic_save_white_24dp</item>
|
||||
|
||||
<item name="conversation_icon_attach_audio">@drawable/ic_audio_dark</item>
|
||||
<item name="conversation_icon_attach_video">@drawable/ic_video_dark</item>
|
||||
|
||||
<item name="reminder_header_background">@color/textsecure_primary_dark</item>
|
||||
|
||||
<item name="pref_ic_push">@drawable/ic_push_gray</item>
|
||||
|
@ -394,7 +394,7 @@ public class ConversationItem extends LinearLayout {
|
||||
public void run() {
|
||||
for (Slide slide : result.getSlides()) {
|
||||
if (slide.hasImage()) {
|
||||
slide.setThumbnailOn(mmsThumbnail);
|
||||
slide.setThumbnailOn(context, mmsThumbnail);
|
||||
mmsThumbnail.setOnClickListener(new ThumbnailClickListener(slide));
|
||||
mmsThumbnail.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
|
@ -80,7 +80,7 @@ public class ImageMediaAdapter extends CursorRecyclerViewAdapter<ViewHolder> {
|
||||
part.setId(imageRecord.getPartId());
|
||||
|
||||
Slide slide = MediaUtil.getSlideForPart(getContext(), masterSecret, part, imageRecord.getContentType());
|
||||
if (slide != null) slide.setThumbnailOn(imageView, gridSize, gridSize, new ColorDrawable(0x11ffffff));
|
||||
if (slide != null) slide.setThumbnailOn(getContext(), imageView, gridSize, gridSize, new ColorDrawable(0x11ffffff));
|
||||
|
||||
imageView.setOnClickListener(new OnMediaClickListener(imageRecord));
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public class AttachmentManager {
|
||||
|
||||
@Override
|
||||
protected Drawable doInBackground(Void... params) {
|
||||
return slide.getThumbnail(thumbnailWidth, thumbnailHeight);
|
||||
return slide.getThumbnail(context, thumbnailWidth, thumbnailHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
@ -28,6 +29,7 @@ import org.w3c.dom.smil.SMILRegionMediaElement;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
@ -64,8 +66,8 @@ public class AudioSlide extends Slide {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
return context.getResources().getDrawable(R.drawable.ic_menu_add_sound);
|
||||
public Drawable getThumbnail(Context context, int maxWidth, int maxHeight) {
|
||||
return ThemeUtil.resolveIcon(context, R.attr.conversation_icon_attach_audio);
|
||||
}
|
||||
|
||||
public static PduPart constructPartFromUri(Context context, Uri uri) throws IOException, MediaTooLargeException {
|
||||
|
@ -70,7 +70,7 @@ public class ImageSlide extends Slide {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
public Drawable getThumbnail(Context context, int maxWidth, int maxHeight) {
|
||||
Drawable thumbnail = getCachedThumbnail();
|
||||
|
||||
if (thumbnail != null) {
|
||||
@ -111,12 +111,12 @@ public class ImageSlide extends Slide {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThumbnailOn(ImageView imageView) {
|
||||
setThumbnailOn(imageView, imageView.getWidth(), imageView.getHeight(), new ColorDrawable(Color.TRANSPARENT));
|
||||
public void setThumbnailOn(Context context, ImageView imageView) {
|
||||
setThumbnailOn(context, imageView, imageView.getWidth(), imageView.getHeight(), new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThumbnailOn(ImageView imageView, final int width, final int height, final Drawable placeholder) {
|
||||
public void setThumbnailOn(Context context, ImageView imageView, final int width, final int height, final Drawable placeholder) {
|
||||
Drawable thumbnail = getCachedThumbnail();
|
||||
|
||||
if (thumbnail != null) {
|
||||
@ -125,6 +125,7 @@ public class ImageSlide extends Slide {
|
||||
return;
|
||||
}
|
||||
|
||||
final WeakReference<Context> weakContext = new WeakReference<>(context);
|
||||
final WeakReference<ImageView> weakImageView = new WeakReference<>(imageView);
|
||||
final Handler handler = new Handler();
|
||||
|
||||
@ -136,7 +137,13 @@ public class ImageSlide extends Slide {
|
||||
MmsDatabase.slideResolver.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Drawable bitmap = getThumbnail(width, height);
|
||||
final Context context = weakContext.get();
|
||||
if (context == null) {
|
||||
Log.w(TAG, "context SoftReference was null, leaving");
|
||||
return;
|
||||
}
|
||||
|
||||
final Drawable bitmap = getThumbnail(context, width, height);
|
||||
final ImageView destination = weakImageView.get();
|
||||
|
||||
Log.w(TAG, "slide resolved, destination available? " + (destination == null));
|
||||
|
@ -30,6 +30,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
@ -70,16 +71,16 @@ public abstract class Slide {
|
||||
return part.getDataUri();
|
||||
}
|
||||
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
public Drawable getThumbnail(Context context, int maxWidth, int maxHeight) {
|
||||
throw new AssertionError("getThumbnail() called on non-thumbnail producing slide!");
|
||||
}
|
||||
|
||||
public void setThumbnailOn(ImageView imageView) {
|
||||
imageView.setImageDrawable(getThumbnail(imageView.getWidth(), imageView.getHeight()));
|
||||
public void setThumbnailOn(Context context, ImageView imageView) {
|
||||
imageView.setImageDrawable(getThumbnail(context, imageView.getWidth(), imageView.getHeight()));
|
||||
}
|
||||
|
||||
public void setThumbnailOn(ImageView imageView, int height, int width, Drawable placeholder) {
|
||||
imageView.setImageDrawable(getThumbnail(width, height));
|
||||
public void setThumbnailOn(Context context, ImageView imageView, int height, int width, Drawable placeholder) {
|
||||
imageView.setImageDrawable(getThumbnail(context, width, height));
|
||||
}
|
||||
|
||||
public Bitmap getGeneratedThumbnail() { return null; }
|
||||
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
@ -28,6 +29,7 @@ import org.w3c.dom.smil.SMILRegionElement;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
@ -45,8 +47,8 @@ public class VideoSlide extends Slide {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int width, int height) {
|
||||
return context.getResources().getDrawable(R.drawable.ic_launcher_video_player);
|
||||
public Drawable getThumbnail(Context context, int width, int height) {
|
||||
return ThemeUtil.resolveIcon(context, R.attr.conversation_icon_attach_video);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
31
src/org/thoughtcrime/securesms/util/ThemeUtil.java
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.TypedValue;
|
||||
|
||||
public class ThemeUtil {
|
||||
public static Drawable resolveIcon(Context c, int iconAttr)
|
||||
{
|
||||
TypedValue out = new TypedValue();
|
||||
c.getTheme().resolveAttribute(iconAttr, out, true);
|
||||
return c.getResources().getDrawable(out.resourceId);
|
||||
}
|
||||
}
|