added epub and azw mime types. try to resolve application/octet-stream by file extension instead. added preview icons for ebooks
| @ -570,7 +570,7 @@ public class FileBackend { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void copyFileToPrivateStorage(Message message, Uri uri, String type) throws FileCopyException { |     public void copyFileToPrivateStorage(Message message, Uri uri, String type) throws FileCopyException { | ||||||
|         String mime = type != null ? type : MimeUtils.guessMimeTypeFromUri(mXmppConnectionService, uri); |         String mime = MimeUtils.guessMimeTypeFromUriAndMime(mXmppConnectionService, uri, type); | ||||||
|         Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage (mime=" + mime + ")"); |         Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage (mime=" + mime + ")"); | ||||||
|         String extension = MimeUtils.guessExtensionFromMimeType(mime); |         String extension = MimeUtils.guessExtensionFromMimeType(mime); | ||||||
|         if (extension == null) { |         if (extension == null) { | ||||||
|  | |||||||
| @ -47,7 +47,7 @@ public class AttachFileToConversationRunnable implements Runnable, MediaTranscod | |||||||
| 		this.mXmppConnectionService = xmppConnectionService; | 		this.mXmppConnectionService = xmppConnectionService; | ||||||
| 		this.message = message; | 		this.message = message; | ||||||
| 		this.callback = callback; | 		this.callback = callback; | ||||||
| 		final String mimeType = type != null ? type : MimeUtils.guessMimeTypeFromUri(mXmppConnectionService, uri); | 		final String mimeType = MimeUtils.guessMimeTypeFromUriAndMime(mXmppConnectionService, uri, type); | ||||||
| 		final int autoAcceptFileSize = mXmppConnectionService.getResources().getInteger(R.integer.auto_accept_filesize); | 		final int autoAcceptFileSize = mXmppConnectionService.getResources().getInteger(R.integer.auto_accept_filesize); | ||||||
| 		this.originalFileSize = FileBackend.getFileSize(mXmppConnectionService,uri); | 		this.originalFileSize = FileBackend.getFileSize(mXmppConnectionService,uri); | ||||||
| 		this.isVideoMessage = (mimeType != null && mimeType.startsWith("video/")) && originalFileSize > autoAcceptFileSize; | 		this.isVideoMessage = (mimeType != null && mimeType.startsWith("video/")) && originalFileSize > autoAcceptFileSize; | ||||||
|  | |||||||
| @ -337,6 +337,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 			query.getConversation().setFirstMamReference(first == null ? null : first.getContent()); | 			query.getConversation().setFirstMamReference(first == null ? null : first.getContent()); | ||||||
| 		} | 		} | ||||||
| 		if (complete || relevant == null || abort) { | 		if (complete || relevant == null || abort) { | ||||||
|  | 			//TODO: FIX done logic to look at complete. using count is probably unreliable because it can be ommited and doesn’t work with paging. | ||||||
| 			boolean done; | 			boolean done; | ||||||
| 			if (query.isCatchup()) { | 			if (query.isCatchup()) { | ||||||
| 				done = false; | 				done = false; | ||||||
|  | |||||||
| @ -77,6 +77,8 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol | |||||||
|                 attr = R.attr.media_preview_app; |                 attr = R.attr.media_preview_app; | ||||||
|             } else if (mime.equals("application/zip") || mime.equals("application/rar")) { |             } else if (mime.equals("application/zip") || mime.equals("application/rar")) { | ||||||
|                 attr = R.attr.media_preview_archive; |                 attr = R.attr.media_preview_archive; | ||||||
|  |             } else if (mime.equals("application/epub+zip") || mime.equals("application/vnd.amazon.mobi8-ebook")) { | ||||||
|  |                 attr = R.attr.media_preview_ebook; | ||||||
|             } else if (DOCUMENT_MIMES.contains(mime)) { |             } else if (DOCUMENT_MIMES.contains(mime)) { | ||||||
|                 attr = R.attr.media_preview_document; |                 attr = R.attr.media_preview_document; | ||||||
|             } else { |             } else { | ||||||
|  | |||||||
| @ -142,13 +142,13 @@ public class Attachment implements Parcelable { | |||||||
|                 for (int i = 0; i < clipData.getItemCount(); ++i) { |                 for (int i = 0; i < clipData.getItemCount(); ++i) { | ||||||
|                     final Uri uri = clipData.getItemAt(i).getUri(); |                     final Uri uri = clipData.getItemAt(i).getUri(); | ||||||
|                     Log.d(Config.LOGTAG,"uri="+uri+" contentType="+contentType); |                     Log.d(Config.LOGTAG,"uri="+uri+" contentType="+contentType); | ||||||
|                     final String mime = contentType != null ? contentType : MimeUtils.guessMimeTypeFromUri(context, uri); |                     final String mime = MimeUtils.guessMimeTypeFromUriAndMime(context, uri, contentType); | ||||||
|                     Log.d(Config.LOGTAG,"mime="+mime); |                     Log.d(Config.LOGTAG,"mime="+mime); | ||||||
|                     uris.add(new Attachment(uri, type, mime)); |                     uris.add(new Attachment(uri, type, mime)); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             final String mime = contentType != null ? contentType : MimeUtils.guessMimeTypeFromUri(context, data); |             final String mime = MimeUtils.guessMimeTypeFromUriAndMime(context, data, contentType); | ||||||
|             uris.add(new Attachment(data, type, mime)); |             uris.add(new Attachment(data, type, mime)); | ||||||
|         } |         } | ||||||
|         return uris; |         return uris; | ||||||
|  | |||||||
| @ -16,6 +16,7 @@ | |||||||
| package eu.siacs.conversations.utils; | package eu.siacs.conversations.utils; | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
|  | import android.util.Log; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileInputStream; | import java.io.FileInputStream; | ||||||
| @ -26,6 +27,7 @@ import java.util.HashMap; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Properties; | import java.util.Properties; | ||||||
| 
 | 
 | ||||||
|  | import eu.siacs.conversations.Config; | ||||||
| import eu.siacs.conversations.entities.Transferable; | import eu.siacs.conversations.entities.Transferable; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -49,6 +51,7 @@ public final class MimeUtils { | |||||||
|         // by guessExtensionFromMimeType. |         // by guessExtensionFromMimeType. | ||||||
|         add("application/andrew-inset", "ez"); |         add("application/andrew-inset", "ez"); | ||||||
|         add("application/dsptype", "tsp"); |         add("application/dsptype", "tsp"); | ||||||
|  |         add("application/epub+zip","pub"); | ||||||
|         add("application/hta", "hta"); |         add("application/hta", "hta"); | ||||||
|         add("application/mac-binhex40", "hqx"); |         add("application/mac-binhex40", "hqx"); | ||||||
|         add("application/mathematica", "nb"); |         add("application/mathematica", "nb"); | ||||||
| @ -64,6 +67,9 @@ public final class MimeUtils { | |||||||
|         add("application/rdf+xml", "rdf"); |         add("application/rdf+xml", "rdf"); | ||||||
|         add("application/rss+xml", "rss"); |         add("application/rss+xml", "rss"); | ||||||
|         add("application/zip", "zip"); |         add("application/zip", "zip"); | ||||||
|  |         add("application/vnd.amazon.mobi8-ebook","azw3"); | ||||||
|  |         add("application/vnd.amazon.mobi8-ebook","azw"); | ||||||
|  |         add("application/vnd.amazon.mobi8-ebook","kfx"); | ||||||
|         add("application/vnd.android.package-archive", "apk"); |         add("application/vnd.android.package-archive", "apk"); | ||||||
|         add("application/vnd.cinderella", "cdy"); |         add("application/vnd.cinderella", "cdy"); | ||||||
|         add("application/vnd.ms-pki.stl", "stl"); |         add("application/vnd.ms-pki.stl", "stl"); | ||||||
| @ -493,6 +499,19 @@ public final class MimeUtils { | |||||||
|         return mimeTypeToExtensionMap.get(mimeType.split(";")[0]); |         return mimeTypeToExtensionMap.get(mimeType.split(";")[0]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static String guessMimeTypeFromUriAndMime(final Context context, final Uri uri, final String mime) { | ||||||
|  |         Log.d(Config.LOGTAG,"guessMimeTypeFromUriAndMime "+uri+" and mime="+mime); | ||||||
|  |         if (mime == null || mime.equals("application/octet-stream")) { | ||||||
|  |             final String guess = guessMimeTypeFromUri(context, uri); | ||||||
|  |             if (guess != null) { | ||||||
|  |                 return guess; | ||||||
|  |             } else { | ||||||
|  |                 return mime; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return guessMimeTypeFromUri(context ,uri); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static String guessMimeTypeFromUri(Context context, Uri uri) { |     public static String guessMimeTypeFromUri(Context context, Uri uri) { | ||||||
|         // try the content resolver |         // try the content resolver | ||||||
|         String mimeType; |         String mimeType; | ||||||
| @ -502,11 +521,14 @@ public final class MimeUtils { | |||||||
|             mimeType = null; |             mimeType = null; | ||||||
|         } |         } | ||||||
|         // try the extension |         // try the extension | ||||||
|         if (mimeType == null && uri.getPath() != null) { |         if ((mimeType == null || mimeType.equals("application/octet-stream")) && uri.getPath() != null) { | ||||||
|             String path = uri.getPath(); |             String path = uri.getPath(); | ||||||
|             int start = path.lastIndexOf('.') + 1; |             int start = path.lastIndexOf('.') + 1; | ||||||
|             if (start < path.length()) { |             if (start < path.length()) { | ||||||
|                 mimeType = MimeUtils.guessMimeTypeFromExtension(path.substring(start)); |                 final String guess = MimeUtils.guessMimeTypeFromExtension(path.substring(start)); | ||||||
|  |                 if (guess != null) { | ||||||
|  |                     mimeType = guess; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         // sometimes this works (as with the commit content api) |         // sometimes this works (as with the commit content api) | ||||||
|  | |||||||
| @ -482,6 +482,8 @@ public class UIHelper { | |||||||
| 			return context.getString(R.string.apk); | 			return context.getString(R.string.apk); | ||||||
| 		} else if (mime.contains("vcard")) { | 		} else if (mime.contains("vcard")) { | ||||||
| 			return context.getString(R.string.vcard); | 			return context.getString(R.string.vcard); | ||||||
|  | 		} else if (mime.equals("application/epub+zip") || mime.equals("application/vnd.amazon.mobi8-ebook")) { | ||||||
|  | 			return context.getString(R.string.ebook); | ||||||
| 		} else { | 		} else { | ||||||
| 			return mime; | 			return mime; | ||||||
| 		} | 		} | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-hdpi/ic_book_black_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 278 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-hdpi/ic_book_white_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 283 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-mdpi/ic_book_black_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 201 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-mdpi/ic_book_white_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 197 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xhdpi/ic_book_black_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 340 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xhdpi/ic_book_white_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 350 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xxhdpi/ic_book_black_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 516 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xxhdpi/ic_book_white_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 532 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xxxhdpi/ic_book_black_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 750 B | 
							
								
								
									
										
											BIN
										
									
								
								src/main/res/drawable-xxxhdpi/ic_book_white_48dp.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 766 B | 
| @ -61,6 +61,7 @@ | |||||||
|     <attr name="media_preview_app" format="reference"/> |     <attr name="media_preview_app" format="reference"/> | ||||||
|     <attr name="media_preview_calendar" format="reference"/> |     <attr name="media_preview_calendar" format="reference"/> | ||||||
|     <attr name="media_preview_archive" format="reference" /> |     <attr name="media_preview_archive" format="reference" /> | ||||||
|  |     <attr name="media_preview_ebook" format="reference"/> | ||||||
|     <attr name="media_preview_unknown" format="reference" /> |     <attr name="media_preview_unknown" format="reference" /> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -804,4 +804,5 @@ | |||||||
|     <string name="start_orbot">Start Orbot</string> |     <string name="start_orbot">Start Orbot</string> | ||||||
|     <string name="no_market_app_installed">No market app installed.</string> |     <string name="no_market_app_installed">No market app installed.</string> | ||||||
|     <string name="group_chat_will_make_your_jabber_id_public">This group chat will make your Jabber ID public</string> |     <string name="group_chat_will_make_your_jabber_id_public">This group chat will make your Jabber ID public</string> | ||||||
|  |     <string name="ebook">e-book</string> | ||||||
| </resources> | </resources> | ||||||
|  | |||||||
| @ -72,6 +72,7 @@ | |||||||
|         <item type="reference" name="media_preview_app">@drawable/ic_android_black_48dp</item> |         <item type="reference" name="media_preview_app">@drawable/ic_android_black_48dp</item> | ||||||
|         <item type="reference" name="media_preview_calendar">@drawable/ic_event_black_48dp</item> |         <item type="reference" name="media_preview_calendar">@drawable/ic_event_black_48dp</item> | ||||||
|         <item type="reference" name="media_preview_archive">@drawable/ic_archive_black_48dp</item> |         <item type="reference" name="media_preview_archive">@drawable/ic_archive_black_48dp</item> | ||||||
|  |         <item type="reference" name="media_preview_ebook">@drawable/ic_book_black_48dp</item> | ||||||
|         <item type="reference" name="media_preview_unknown">@drawable/ic_help_black_48dp</item> |         <item type="reference" name="media_preview_unknown">@drawable/ic_help_black_48dp</item> | ||||||
| 
 | 
 | ||||||
|         <item type="reference" name="icon_add_group">@drawable/ic_group_add_white_24dp</item> |         <item type="reference" name="icon_add_group">@drawable/ic_group_add_white_24dp</item> | ||||||
| @ -184,6 +185,7 @@ | |||||||
|         <item type="reference" name="media_preview_app">@drawable/ic_android_white_48dp</item> |         <item type="reference" name="media_preview_app">@drawable/ic_android_white_48dp</item> | ||||||
|         <item type="reference" name="media_preview_calendar">@drawable/ic_event_white_48dp</item> |         <item type="reference" name="media_preview_calendar">@drawable/ic_event_white_48dp</item> | ||||||
|         <item type="reference" name="media_preview_archive">@drawable/ic_archive_white_48dp</item> |         <item type="reference" name="media_preview_archive">@drawable/ic_archive_white_48dp</item> | ||||||
|  |         <item type="reference" name="media_preview_ebook">@drawable/ic_book_white_48dp</item> | ||||||
|         <item type="reference" name="media_preview_unknown">@drawable/ic_help_white_48dp</item> |         <item type="reference" name="media_preview_unknown">@drawable/ic_help_white_48dp</item> | ||||||
| 
 | 
 | ||||||
|         <item type="reference" name="icon_add_group">@drawable/ic_group_add_white_24dp</item> |         <item type="reference" name="icon_add_group">@drawable/ic_group_add_white_24dp</item> | ||||||
|  | |||||||
 Daniel Gultsch
						Daniel Gultsch