From 53fea9e1fe25a1f0f2a7fe219195b0009ecb4f5b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 11:38:56 +0200 Subject: replace send button with quick action button as long as no text has been entered --- art/ic_action_send_now.svg | 69 -- art/ic_received_indicator.svg | 16 +- art/ic_send_location_away.svg | 54 ++ art/ic_send_location_dnd.svg | 54 ++ art/ic_send_location_offline.svg | 54 ++ art/ic_send_location_online.svg | 54 ++ art/ic_send_photo_away.svg | 60 ++ art/ic_send_photo_dnd.svg | 60 ++ art/ic_send_photo_offline.svg | 60 ++ art/ic_send_photo_online.svg | 60 ++ art/ic_send_text_away.svg | 69 ++ art/ic_send_text_dnd.svg | 69 ++ art/ic_send_text_offline.svg | 69 ++ art/ic_send_text_online.svg | 69 ++ art/ic_send_voice_away.svg | 54 ++ art/ic_send_voice_dnd.svg | 54 ++ art/ic_send_voice_offline.svg | 54 ++ art/ic_send_voice_online.svg | 54 ++ art/render.rb | 16 + .../conversations/ui/ConversationActivity.java | 23 +- .../conversations/ui/ConversationFragment.java | 275 ++++--- .../res/drawable-hdpi/ic_action_send_now_away.png | Bin 932 -> 0 bytes .../res/drawable-hdpi/ic_action_send_now_dnd.png | Bin 1135 -> 0 bytes .../drawable-hdpi/ic_action_send_now_offline.png | Bin 767 -> 0 bytes .../drawable-hdpi/ic_action_send_now_online.png | Bin 1095 -> 0 bytes src/main/res/drawable-hdpi/ic_launcher.png | Bin 4497 -> 4486 bytes src/main/res/drawable-hdpi/ic_notification.png | Bin 806 -> 798 bytes .../res/drawable-hdpi/ic_received_indicator.png | Bin 686 -> 560 bytes .../res/drawable-hdpi/ic_send_location_away.png | Bin 0 -> 1159 bytes .../res/drawable-hdpi/ic_send_location_dnd.png | Bin 0 -> 1333 bytes .../res/drawable-hdpi/ic_send_location_offline.png | Bin 0 -> 971 bytes .../res/drawable-hdpi/ic_send_location_online.png | Bin 0 -> 1341 bytes src/main/res/drawable-hdpi/ic_send_photo_away.png | Bin 0 -> 1203 bytes src/main/res/drawable-hdpi/ic_send_photo_dnd.png | Bin 0 -> 1381 bytes .../res/drawable-hdpi/ic_send_photo_offline.png | Bin 0 -> 987 bytes .../res/drawable-hdpi/ic_send_photo_online.png | Bin 0 -> 1400 bytes src/main/res/drawable-hdpi/ic_send_text_away.png | Bin 0 -> 982 bytes src/main/res/drawable-hdpi/ic_send_text_dnd.png | Bin 0 -> 1126 bytes .../res/drawable-hdpi/ic_send_text_offline.png | Bin 0 -> 800 bytes src/main/res/drawable-hdpi/ic_send_text_online.png | Bin 0 -> 1143 bytes src/main/res/drawable-hdpi/ic_send_voice_away.png | Bin 0 -> 1017 bytes src/main/res/drawable-hdpi/ic_send_voice_dnd.png | Bin 0 -> 1149 bytes .../res/drawable-hdpi/ic_send_voice_offline.png | Bin 0 -> 844 bytes .../res/drawable-hdpi/ic_send_voice_online.png | Bin 0 -> 1162 bytes .../res/drawable-mdpi/ic_action_send_now_away.png | Bin 650 -> 0 bytes .../res/drawable-mdpi/ic_action_send_now_dnd.png | Bin 784 -> 0 bytes .../drawable-mdpi/ic_action_send_now_offline.png | Bin 535 -> 0 bytes .../drawable-mdpi/ic_action_send_now_online.png | Bin 779 -> 0 bytes src/main/res/drawable-mdpi/ic_launcher.png | Bin 2741 -> 2762 bytes src/main/res/drawable-mdpi/ic_notification.png | Bin 553 -> 554 bytes .../res/drawable-mdpi/ic_received_indicator.png | Bin 447 -> 402 bytes .../res/drawable-mdpi/ic_send_location_away.png | Bin 0 -> 784 bytes .../res/drawable-mdpi/ic_send_location_dnd.png | Bin 0 -> 908 bytes .../res/drawable-mdpi/ic_send_location_offline.png | Bin 0 -> 673 bytes .../res/drawable-mdpi/ic_send_location_online.png | Bin 0 -> 919 bytes src/main/res/drawable-mdpi/ic_send_photo_away.png | Bin 0 -> 776 bytes src/main/res/drawable-mdpi/ic_send_photo_dnd.png | Bin 0 -> 909 bytes .../res/drawable-mdpi/ic_send_photo_offline.png | Bin 0 -> 666 bytes .../res/drawable-mdpi/ic_send_photo_online.png | Bin 0 -> 938 bytes src/main/res/drawable-mdpi/ic_send_text_away.png | Bin 0 -> 677 bytes src/main/res/drawable-mdpi/ic_send_text_dnd.png | Bin 0 -> 769 bytes .../res/drawable-mdpi/ic_send_text_offline.png | Bin 0 -> 542 bytes src/main/res/drawable-mdpi/ic_send_text_online.png | Bin 0 -> 793 bytes src/main/res/drawable-mdpi/ic_send_voice_away.png | Bin 0 -> 679 bytes src/main/res/drawable-mdpi/ic_send_voice_dnd.png | Bin 0 -> 774 bytes .../res/drawable-mdpi/ic_send_voice_offline.png | Bin 0 -> 575 bytes .../res/drawable-mdpi/ic_send_voice_online.png | Bin 0 -> 788 bytes .../res/drawable-xhdpi/ic_action_send_now_away.png | Bin 1180 -> 0 bytes .../res/drawable-xhdpi/ic_action_send_now_dnd.png | Bin 1438 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_offline.png | Bin 968 -> 0 bytes .../drawable-xhdpi/ic_action_send_now_online.png | Bin 1395 -> 0 bytes src/main/res/drawable-xhdpi/ic_launcher.png | Bin 6336 -> 6377 bytes src/main/res/drawable-xhdpi/ic_notification.png | Bin 1079 -> 1075 bytes .../res/drawable-xhdpi/ic_received_indicator.png | Bin 855 -> 717 bytes .../res/drawable-xhdpi/ic_send_location_away.png | Bin 0 -> 1507 bytes .../res/drawable-xhdpi/ic_send_location_dnd.png | Bin 0 -> 1721 bytes .../drawable-xhdpi/ic_send_location_offline.png | Bin 0 -> 1278 bytes .../res/drawable-xhdpi/ic_send_location_online.png | Bin 0 -> 1751 bytes src/main/res/drawable-xhdpi/ic_send_photo_away.png | Bin 0 -> 1516 bytes src/main/res/drawable-xhdpi/ic_send_photo_dnd.png | Bin 0 -> 1723 bytes .../res/drawable-xhdpi/ic_send_photo_offline.png | Bin 0 -> 1247 bytes .../res/drawable-xhdpi/ic_send_photo_online.png | Bin 0 -> 1755 bytes src/main/res/drawable-xhdpi/ic_send_text_away.png | Bin 0 -> 1270 bytes src/main/res/drawable-xhdpi/ic_send_text_dnd.png | Bin 0 -> 1395 bytes .../res/drawable-xhdpi/ic_send_text_offline.png | Bin 0 -> 1007 bytes .../res/drawable-xhdpi/ic_send_text_online.png | Bin 0 -> 1468 bytes src/main/res/drawable-xhdpi/ic_send_voice_away.png | Bin 0 -> 1257 bytes src/main/res/drawable-xhdpi/ic_send_voice_dnd.png | Bin 0 -> 1426 bytes .../res/drawable-xhdpi/ic_send_voice_offline.png | Bin 0 -> 1075 bytes .../res/drawable-xhdpi/ic_send_voice_online.png | Bin 0 -> 1433 bytes .../drawable-xxhdpi/ic_action_send_now_away.png | Bin 1426 -> 0 bytes .../res/drawable-xxhdpi/ic_action_send_now_dnd.png | Bin 1456 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_offline.png | Bin 1433 -> 0 bytes .../drawable-xxhdpi/ic_action_send_now_online.png | Bin 1458 -> 0 bytes src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 10221 -> 10254 bytes src/main/res/drawable-xxhdpi/ic_notification.png | Bin 1573 -> 1618 bytes .../res/drawable-xxhdpi/ic_received_indicator.png | Bin 1236 -> 1016 bytes .../res/drawable-xxhdpi/ic_send_location_away.png | Bin 0 -> 2229 bytes .../res/drawable-xxhdpi/ic_send_location_dnd.png | Bin 0 -> 2578 bytes .../drawable-xxhdpi/ic_send_location_offline.png | Bin 0 -> 1881 bytes .../drawable-xxhdpi/ic_send_location_online.png | Bin 0 -> 2605 bytes .../res/drawable-xxhdpi/ic_send_photo_away.png | Bin 0 -> 2256 bytes src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png | Bin 0 -> 2588 bytes .../res/drawable-xxhdpi/ic_send_photo_offline.png | Bin 0 -> 1802 bytes .../res/drawable-xxhdpi/ic_send_photo_online.png | Bin 0 -> 2571 bytes src/main/res/drawable-xxhdpi/ic_send_text_away.png | Bin 0 -> 1776 bytes src/main/res/drawable-xxhdpi/ic_send_text_dnd.png | Bin 0 -> 2004 bytes .../res/drawable-xxhdpi/ic_send_text_offline.png | Bin 0 -> 1410 bytes .../res/drawable-xxhdpi/ic_send_text_online.png | Bin 0 -> 2001 bytes .../res/drawable-xxhdpi/ic_send_voice_away.png | Bin 0 -> 1895 bytes src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png | Bin 0 -> 2152 bytes .../res/drawable-xxhdpi/ic_send_voice_offline.png | Bin 0 -> 1621 bytes .../res/drawable-xxhdpi/ic_send_voice_online.png | Bin 0 -> 2183 bytes src/main/res/drawable-xxxhdpi/ic_launcher.png | Bin 14234 -> 14117 bytes src/main/res/drawable-xxxhdpi/ic_notification.png | Bin 2063 -> 2117 bytes .../res/drawable-xxxhdpi/ic_received_indicator.png | Bin 1608 -> 1303 bytes .../res/drawable-xxxhdpi/ic_send_location_away.png | Bin 0 -> 3015 bytes .../res/drawable-xxxhdpi/ic_send_location_dnd.png | Bin 0 -> 3456 bytes .../drawable-xxxhdpi/ic_send_location_offline.png | Bin 0 -> 2523 bytes .../drawable-xxxhdpi/ic_send_location_online.png | Bin 0 -> 3514 bytes .../res/drawable-xxxhdpi/ic_send_photo_away.png | Bin 0 -> 3040 bytes .../res/drawable-xxxhdpi/ic_send_photo_dnd.png | Bin 0 -> 3544 bytes .../res/drawable-xxxhdpi/ic_send_photo_offline.png | Bin 0 -> 2491 bytes .../res/drawable-xxxhdpi/ic_send_photo_online.png | Bin 0 -> 3566 bytes .../res/drawable-xxxhdpi/ic_send_text_away.png | Bin 0 -> 2311 bytes src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png | Bin 0 -> 2597 bytes .../res/drawable-xxxhdpi/ic_send_text_offline.png | Bin 0 -> 1862 bytes .../res/drawable-xxxhdpi/ic_send_text_online.png | Bin 0 -> 2708 bytes .../res/drawable-xxxhdpi/ic_send_voice_away.png | Bin 0 -> 2491 bytes .../res/drawable-xxxhdpi/ic_send_voice_dnd.png | Bin 0 -> 2811 bytes .../res/drawable-xxxhdpi/ic_send_voice_offline.png | Bin 0 -> 2092 bytes .../res/drawable-xxxhdpi/ic_send_voice_online.png | Bin 0 -> 2868 bytes src/main/res/layout/fragment_conversation.xml | 2 +- src/main/res/values/arrays.xml | 15 + src/main/res/values/strings.xml | 813 +++++++++++---------- src/main/res/xml/preferences.xml | 8 + 136 files changed, 1597 insertions(+), 588 deletions(-) delete mode 100644 art/ic_action_send_now.svg create mode 100644 art/ic_send_location_away.svg create mode 100644 art/ic_send_location_dnd.svg create mode 100644 art/ic_send_location_offline.svg create mode 100644 art/ic_send_location_online.svg create mode 100644 art/ic_send_photo_away.svg create mode 100644 art/ic_send_photo_dnd.svg create mode 100644 art/ic_send_photo_offline.svg create mode 100644 art/ic_send_photo_online.svg create mode 100644 art/ic_send_text_away.svg create mode 100644 art/ic_send_text_dnd.svg create mode 100644 art/ic_send_text_offline.svg create mode 100644 art/ic_send_text_online.svg create mode 100644 art/ic_send_voice_away.svg create mode 100644 art/ic_send_voice_dnd.svg create mode 100644 art/ic_send_voice_offline.svg create mode 100644 art/ic_send_voice_online.svg delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-hdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-mdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-xhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_voice_online.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_away.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_action_send_now_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_voice_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_location_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_photo_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_text_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_voice_online.png diff --git a/art/ic_action_send_now.svg b/art/ic_action_send_now.svg deleted file mode 100644 index 6bde9158..00000000 --- a/art/ic_action_send_now.svg +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/art/ic_received_indicator.svg b/art/ic_received_indicator.svg index d9378c60..43689c26 100644 --- a/art/ic_received_indicator.svg +++ b/art/ic_received_indicator.svg @@ -13,7 +13,7 @@ width="95" height="95" id="Yes_check" - inkscape:version="0.48.5 r10040" + inkscape:version="0.91 r13725" sodipodi:docname="ic_received_indicator.svg"> @@ -23,7 +23,7 @@ image/svg+xml - + @@ -36,17 +36,17 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1233" - inkscape:window-height="828" + inkscape:window-width="956" + inkscape:window-height="1156" id="namedview8" showgrid="false" showguides="true" inkscape:guide-bbox="true" inkscape:zoom="5.04" - inkscape:cx="26.829268" + inkscape:cx="-4.3215257" inkscape:cy="37.489149" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:window-x="2880" + inkscape:window-y="20" inkscape:window-maximized="0" inkscape:current-layer="Yes_check" fit-margin-top="0" @@ -69,7 +69,7 @@ diff --git a/art/ic_send_location_away.svg b/art/ic_send_location_away.svg new file mode 100644 index 00000000..fcd50b52 --- /dev/null +++ b/art/ic_send_location_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_dnd.svg b/art/ic_send_location_dnd.svg new file mode 100644 index 00000000..d91fa913 --- /dev/null +++ b/art/ic_send_location_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_offline.svg b/art/ic_send_location_offline.svg new file mode 100644 index 00000000..56529b72 --- /dev/null +++ b/art/ic_send_location_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_location_online.svg b/art/ic_send_location_online.svg new file mode 100644 index 00000000..275a7a78 --- /dev/null +++ b/art/ic_send_location_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_photo_away.svg b/art/ic_send_photo_away.svg new file mode 100644 index 00000000..31a20e09 --- /dev/null +++ b/art/ic_send_photo_away.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_dnd.svg b/art/ic_send_photo_dnd.svg new file mode 100644 index 00000000..0e406ede --- /dev/null +++ b/art/ic_send_photo_dnd.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_offline.svg b/art/ic_send_photo_offline.svg new file mode 100644 index 00000000..b2ca20a6 --- /dev/null +++ b/art/ic_send_photo_offline.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_photo_online.svg b/art/ic_send_photo_online.svg new file mode 100644 index 00000000..79f71347 --- /dev/null +++ b/art/ic_send_photo_online.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/art/ic_send_text_away.svg b/art/ic_send_text_away.svg new file mode 100644 index 00000000..ea83086a --- /dev/null +++ b/art/ic_send_text_away.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_dnd.svg b/art/ic_send_text_dnd.svg new file mode 100644 index 00000000..b594f319 --- /dev/null +++ b/art/ic_send_text_dnd.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_offline.svg b/art/ic_send_text_offline.svg new file mode 100644 index 00000000..c87bfaac --- /dev/null +++ b/art/ic_send_text_offline.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_text_online.svg b/art/ic_send_text_online.svg new file mode 100644 index 00000000..39e3d1e8 --- /dev/null +++ b/art/ic_send_text_online.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/art/ic_send_voice_away.svg b/art/ic_send_voice_away.svg new file mode 100644 index 00000000..379f55b7 --- /dev/null +++ b/art/ic_send_voice_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_dnd.svg b/art/ic_send_voice_dnd.svg new file mode 100644 index 00000000..372a2ca8 --- /dev/null +++ b/art/ic_send_voice_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_offline.svg b/art/ic_send_voice_offline.svg new file mode 100644 index 00000000..64ea4473 --- /dev/null +++ b/art/ic_send_voice_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_voice_online.svg b/art/ic_send_voice_online.svg new file mode 100644 index 00000000..97284b02 --- /dev/null +++ b/art/ic_send_voice_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 2ab3e94f..32d06f8f 100755 --- a/art/render.rb +++ b/art/render.rb @@ -10,6 +10,22 @@ images = { 'conversations_baloon.svg' => ['ic_launcher', 48], 'conversations_mono.svg' => ['ic_notification', 24], 'ic_received_indicator.svg' => ['ic_received_indicator', 12], + 'ic_send_text_offline.svg' => ['ic_send_text_offline', 36], + 'ic_send_text_online.svg' => ['ic_send_text_online', 36], + 'ic_send_text_away.svg' => ['ic_send_text_away', 36], + 'ic_send_text_dnd.svg' => ['ic_send_text_dnd', 36], + 'ic_send_photo_online.svg' => ['ic_send_photo_online', 36], + 'ic_send_photo_offline.svg' => ['ic_send_photo_offline', 36], + 'ic_send_photo_away.svg' => ['ic_send_photo_away', 36], + 'ic_send_photo_dnd.svg' => ['ic_send_photo_dnd', 36], + 'ic_send_location_online.svg' => ['ic_send_location_online', 36], + 'ic_send_location_offline.svg' => ['ic_send_location_offline', 36], + 'ic_send_location_away.svg' => ['ic_send_location_away', 36], + 'ic_send_location_dnd.svg' => ['ic_send_location_dnd', 36], + 'ic_send_voice_online.svg' => ['ic_send_voice_online', 36], + 'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36], + 'ic_send_voice_away.svg' => ['ic_send_voice_away', 36], + 'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36], } images.each do |source, result| resolutions.each do |name, factor| diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index aec755fc..a76efbc3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -60,11 +60,11 @@ public class ConversationActivity extends XmppActivity public static final int REQUEST_SEND_MESSAGE = 0x0201; public static final int REQUEST_DECRYPT_PGP = 0x0202; public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207; - private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; - private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; - private static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; - private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304; - private static final int ATTACHMENT_CHOICE_LOCATION = 0x0305; + public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; + public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; + public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; + public static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304; + public static final int ATTACHMENT_CHOICE_LOCATION = 0x0305; private static final String STATE_OPEN_CONVERSATION = "state_open_conversation"; private static final String STATE_PANEL_OPEN = "state_panel_open"; private static final String STATE_PENDING_URI = "state_pending_uri"; @@ -452,7 +452,18 @@ public class ConversationActivity extends XmppActivity } } - private void attachFile(final int attachmentChoice) { + public void attachFile(final int attachmentChoice) { + switch (attachmentChoice) { + case ATTACHMENT_CHOICE_LOCATION: + getPreferences().edit().putString("recently_used_quick_action","location").apply(); + break; + case ATTACHMENT_CHOICE_RECORD_VOICE: + getPreferences().edit().putString("recently_used_quick_action","voice").apply(); + break; + case ATTACHMENT_CHOICE_TAKE_PHOTO: + getPreferences().edit().putString("recently_used_quick_action","photo").apply(); + break; + } final Conversation conversation = getSelectedConversation(); final int encryption = conversation.getNextEncryption(forceEncryption()); if (encryption == Message.ENCRYPTION_PGP) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5b1e9b4d..37ae00a3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -119,7 +119,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { + int visibleItemCount, int totalItemCount) { synchronized (ConversationFragment.this.messageList) { if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) { long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent(); @@ -145,7 +145,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa try { Message tmpMessage = messageList.get(newPosition); - while(tmpMessage.wasMergedIntoPrevious()) { + while (tmpMessage.wasMergedIntoPrevious()) { offset++; tmpMessage = tmpMessage.prev(); } @@ -174,7 +174,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (ConversationFragment.this.conversation != conversation) { return; } - messageLoaderToast = Toast.makeText(activity,resId,Toast.LENGTH_LONG); + messageLoaderToast = Toast.makeText(activity, resId, Toast.LENGTH_LONG); messageLoaderToast.show(); } }); @@ -208,7 +208,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - activity.verifyOtrSessionDialog(conversation,v); + activity.verifyOtrSessionDialog(conversation, v); } }; private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue<>(); @@ -219,7 +219,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEND) { InputMethodManager imm = (InputMethodManager) v.getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE); + .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); sendMessage(); return true; @@ -232,7 +232,25 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - sendMessage(); + Object tag = v.getTag(); + if (tag instanceof SendButtonAction) { + SendButtonAction action = (SendButtonAction) tag; + switch (action) { + case TAKE_PHOTO: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_TAKE_PHOTO); + break; + case SEND_LOCATION: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_LOCATION); + break; + case RECORD_VOICE: + activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_RECORD_VOICE); + break; + default: + sendMessage(); + } + } else { + sendMessage(); + } } }; private OnClickListener clickToMuc = new OnClickListener() { @@ -262,7 +280,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } Message message = new Message(conversation, mEditMessage.getText() .toString(), conversation.getNextEncryption(activity - .forceEncryption())); + .forceEncryption())); if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getNextCounterpart() != null) { message.setCounterpart(conversation.getNextCounterpart()); @@ -282,13 +300,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMode() == Conversation.MODE_MULTI && conversation.getNextCounterpart() != null) { this.mEditMessage.setHint(getString( - R.string.send_private_message_to, - conversation.getNextCounterpart().getResourcepart())); + R.string.send_private_message_to, + conversation.getNextCounterpart().getResourcepart())); } else { switch (conversation.getNextEncryption(activity.forceEncryption())) { case Message.ENCRYPTION_NONE: mEditMessage - .setHint(getString(R.string.send_plain_text_message)); + .setHint(getString(R.string.send_plain_text_message)); break; case Message.ENCRYPTION_OTR: mEditMessage.setHint(getString(R.string.send_otr_message)); @@ -304,7 +322,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } private void setupIme() { - if (((ConversationActivity)getActivity()).usingEnterKey()) { + if (((ConversationActivity) getActivity()).usingEnterKey()) { mEditMessage.setInputType(mEditMessage.getInputType() & (~InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE)); } else { mEditMessage.setInputType(mEditMessage.getInputType() | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE); @@ -313,8 +331,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public View onCreateView(final LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.fragment_conversation,container, false); + ViewGroup container, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.fragment_conversation, container, false); view.setOnClickListener(null); mEditMessage = (EditMessage) view.findViewById(R.id.textinput); setupIme(); @@ -365,21 +383,21 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } }); messageListAdapter - .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { + .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { - @Override - public void onContactPictureLongClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getCounterpart() != null) { - privateMessageWith(message.getCounterpart()); + @Override + public void onContactPictureLongClicked(Message message) { + if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getCounterpart() != null) { + privateMessageWith(message.getCounterpart()); + } } + } else { + activity.showQrCode(); } - } else { - activity.showQrCode(); } - } - }); + }); messagesView.setAdapter(messageListAdapter); registerForContextMenu(messagesView); @@ -389,7 +407,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { + ContextMenuInfo menuInfo) { synchronized (this.messageList) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; @@ -416,7 +434,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE || m.getDownloadable() != null) - && (!GeoHelper.isGeoUri(m.getBody()))) { + && (!GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(false); } if (m.getStatus() != Message.STATUS_SEND_FAILED) { @@ -425,17 +443,17 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) || m.getImageParams().url == null) && !GeoHelper.isGeoUri(m.getBody())) { copyUrl.setVisible(false); - } + } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null || !m.bodyContainsDownloadable()) { downloadImage.setVisible(false); - } + } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) - || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING - || m.getStatus() == Message.STATUS_OFFERED)))) { + || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING + || m.getStatus() == Message.STATUS_OFFERED)))) { cancelTransmission.setVisible(false); - } + } } } @@ -483,12 +501,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } shareIntent.setType(mime); } - activity.startActivity(Intent.createChooser(shareIntent,getText(R.string.share_with))); + activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with))); } private void copyText(Message message) { if (activity.copyTextToClipboard(message.getMergedBody(), - R.string.message_text)) { + R.string.message_text)) { Toast.makeText(activity, R.string.message_copied_to_clipboard, Toast.LENGTH_SHORT).show(); } @@ -498,7 +516,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) { DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { - Toast.makeText(activity,R.string.file_deleted,Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); return; } @@ -519,20 +537,20 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (activity.copyTextToClipboard(url, resId)) { Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show(); - } + } } private void downloadImage(Message message) { activity.xmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + .createNewConnection(message); } private void cancelTransmission(Message message) { Downloadable downloadable = message.getDownloadable(); - if (downloadable!=null) { + if (downloadable != null) { downloadable.cancel(); } else { - activity.xmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED); + activity.xmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); } } @@ -548,9 +566,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa mEditMessage.getText().insert(0, nick + ": "); } else { if (mEditMessage.getText().charAt( - mEditMessage.getSelectionStart() - 1) != ' ') { + mEditMessage.getSelectionStart() - 1) != ' ') { nick = " " + nick; - } + } mEditMessage.getText().insert(mEditMessage.getSelectionStart(), nick + " "); } @@ -563,7 +581,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (this.conversation != null) { final String msg = mEditMessage.getText().toString(); this.conversation.setNextMessage(msg); - updateChatState(this.conversation,msg); + updateChatState(this.conversation, msg); } } @@ -586,7 +604,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final String msg = mEditMessage.getText().toString(); this.conversation.setNextMessage(msg); if (this.conversation != conversation) { - updateChatState(this.conversation,msg); + updateChatState(this.conversation, msg); } this.conversation.trim(); } @@ -632,7 +650,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - final Contact contact = conversation == null ? null :conversation.getContact(); + final Contact contact = conversation == null ? null : conversation.getContact(); if (contact != null) { activity.xmppConnectionService.createContact(contact); activity.switchToContactDetails(contact); @@ -655,7 +673,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT); intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString()); intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString()); - intent.putExtra("mode",VerifyOTRActivity.MODE_ANSWER_QUESTION); + intent.putExtra("mode", VerifyOTRActivity.MODE_ANSWER_QUESTION); startActivity(intent); } }; @@ -665,11 +683,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final Contact contact = conversation.getContact(); final int mode = conversation.getMode(); if (conversation.isBlocked()) { - showSnackbar(R.string.contact_blocked, R.string.unblock,this.mUnblockClickListener); + showSnackbar(R.string.contact_blocked, R.string.unblock, this.mUnblockClickListener); } else if (!contact.showInRoster() && contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - showSnackbar(R.string.contact_added_you, R.string.add_back,this.mAddBackClickListener); + showSnackbar(R.string.contact_added_you, R.string.add_back, this.mAddBackClickListener); } else if (mode == Conversation.MODE_MULTI - &&!conversation.getMucOptions().online() + && !conversation.getMucOptions().online() && account.getStatus() == Account.State.ONLINE) { switch (conversation.getMucOptions().getError()) { case MucOptions.ERROR_NICK_IN_USE: @@ -693,18 +711,18 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa default: break; } - } else if (askForPassphraseIntent != null ) { - showSnackbar(R.string.openpgp_messages_found,R.string.decrypt, clickToDecryptListener); + } else if (askForPassphraseIntent != null) { + showSnackbar(R.string.openpgp_messages_found, R.string.decrypt, clickToDecryptListener); } else if (mode == Conversation.MODE_SINGLE && conversation.smpRequested()) { - showSnackbar(R.string.smp_requested, R.string.verify,this.mAnswerSmpClickListener); + showSnackbar(R.string.smp_requested, R.string.verify, this.mAnswerSmpClickListener); } else if (mode == Conversation.MODE_SINGLE - &&conversation.hasValidOtrSession() + && conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!conversation.isOtrFingerprintVerified())) { showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify); } else if (conversation.isMuted()) { - showSnackbar(R.string.notifications_disabled, R.string.enable,this.mUnmuteClickListener); + showSnackbar(R.string.notifications_disabled, R.string.enable, this.mUnmuteClickListener); } else { hideSnackbar(); } @@ -722,12 +740,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP && (message.getStatus() == Message.STATUS_RECEIVED || message - .getStatus() >= Message.STATUS_SEND) + .getStatus() >= Message.STATUS_SEND) && message.getDownloadable() == null) { if (!mEncryptedMessages.contains(message)) { mEncryptedMessages.add(message); } - } + } } decryptNext(); updateStatusMessages(); @@ -790,53 +808,108 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateChatMsgHint(); } - public void updateSendButton() { - Conversation c = this.conversation; - if (activity.useSendButtonToIndicateStatus() && c != null - && c.getAccount().getStatus() == Account.State.ONLINE) { - if (c.getMode() == Conversation.MODE_SINGLE) { - switch (c.getContact().getMostAvailableStatus()) { + enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE} + + private int getSendButtonImageResource(SendButtonAction action, int status) { + switch (action) { + case TEXT: + switch (status) { case Presences.CHAT: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; case Presences.ONLINE: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - break; + return R.drawable.ic_send_text_online; case Presences.AWAY: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; + return R.drawable.ic_send_text_away; case Presences.XA: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_away); - break; case Presences.DND: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_dnd); + return R.drawable.ic_send_text_dnd; + default: + return R.drawable.ic_send_text_offline; + } + case TAKE_PHOTO: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_photo_online; + case Presences.AWAY: + return R.drawable.ic_send_photo_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_photo_dnd; + default: + return R.drawable.ic_send_photo_offline; + } + case RECORD_VOICE: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_voice_online; + case Presences.AWAY: + return R.drawable.ic_send_voice_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_voice_dnd; + default: + return R.drawable.ic_send_voice_offline; + } + case SEND_LOCATION: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_location_online; + case Presences.AWAY: + return R.drawable.ic_send_location_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_location_dnd; + default: + return R.drawable.ic_send_location_offline; + } + } + return R.drawable.ic_send_text_offline; + } + + public void updateSendButton() { + final Conversation c = this.conversation; + final SendButtonAction action; + final int status; + if (c.getMode() == Conversation.MODE_MULTI) { + action = SendButtonAction.TEXT; + } else { + if (this.mEditMessage == null || this.mEditMessage.getText().length() == 0) { + String setting = activity.getPreferences().getString("quick_action","recent"); + if (setting.equals("recent")) { + setting = activity.getPreferences().getString("recently_used_quick_action","text"); + } + switch (setting) { + case "photo": + action = SendButtonAction.TAKE_PHOTO; + break; + case "location": + action = SendButtonAction.SEND_LOCATION; + break; + case "voice": + action = SendButtonAction.RECORD_VOICE; break; default: - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + action = SendButtonAction.TEXT; break; } - } else if (c.getMode() == Conversation.MODE_MULTI) { - if (c.getMucOptions().online()) { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_online); - } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); - } } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + action = SendButtonAction.TEXT; + } + } + if (activity.useSendButtonToIndicateStatus() && c != null + && c.getAccount().getStatus() == Account.State.ONLINE) { + if (c.getMode() == Conversation.MODE_SINGLE) { + status = c.getContact().getMostAvailableStatus(); + } else { + status = c.getMucOptions().online() ? Presences.ONLINE : Presences.OFFLINE; } } else { - this.mSendButton - .setImageResource(R.drawable.ic_action_send_now_offline); + status = Presences.OFFLINE; } + this.mSendButton.setTag(action); + this.mSendButton.setImageResource(getSendButtonImageResource(action, status)); } protected void updateStatusMessages() { @@ -865,7 +938,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } protected void showSnackbar(final int message, final int action, - final OnClickListener clickListener) { + final OnClickListener clickListener) { snackbar.setVisibility(View.VISIBLE); snackbar.setOnClickListener(null); snackbarMessage.setText(message); @@ -897,7 +970,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void userInputRequried(PendingIntent pi, - Contact contact) { + Contact contact) { activity.runIntent( pi, ConversationActivity.REQUEST_ENCRYPT_MESSAGE); @@ -921,11 +994,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(DialogInterface dialog, - int which) { + int which) { conversation - .setNextEncryption(Message.ENCRYPTION_NONE); + .setNextEncryption(Message.ENCRYPTION_NONE); xmppService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.sendMessage(message); messageSent(); @@ -936,9 +1009,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMucOptions().pgpKeysInUse()) { if (!conversation.getMucOptions().everybodyHasKeys()) { Toast warning = Toast - .makeText(getActivity(), - R.string.missing_public_keys, - Toast.LENGTH_LONG); + .makeText(getActivity(), + R.string.missing_public_keys, + Toast.LENGTH_LONG); warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0); warning.show(); } @@ -950,12 +1023,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(DialogInterface dialog, - int which) { + int which) { conversation - .setNextEncryption(Message.ENCRYPTION_NONE); + .setNextEncryption(Message.ENCRYPTION_NONE); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); xmppService.sendMessage(message); messageSent(); } @@ -968,7 +1041,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } public void showNoPGPKeyDialog(boolean plural, - DialogInterface.OnClickListener listener) { + DialogInterface.OnClickListener listener) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setIconAttribute(android.R.attr.alertDialogIcon); if (plural) { @@ -1026,6 +1099,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (status == Account.State.ONLINE && conversation.setOutgoingChatState(ChatState.COMPOSING)) { activity.xmppConnectionService.sendChatState(conversation); } + updateSendButton(); } @Override @@ -1042,6 +1116,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (status == Account.State.ONLINE && conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) { activity.xmppConnectionService.sendChatState(conversation); } + updateSendButton(); } } diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_away.png b/src/main/res/drawable-hdpi/ic_action_send_now_away.png deleted file mode 100644 index 505cbe63..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a376524d..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_offline.png b/src/main/res/drawable-hdpi/ic_action_send_now_offline.png deleted file mode 100644 index d4d2d510..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_action_send_now_online.png b/src/main/res/drawable-hdpi/ic_action_send_now_online.png deleted file mode 100644 index 48676f7b..00000000 Binary files a/src/main/res/drawable-hdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-hdpi/ic_launcher.png b/src/main/res/drawable-hdpi/ic_launcher.png index bffc1c65..25fc8591 100644 Binary files a/src/main/res/drawable-hdpi/ic_launcher.png and b/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-hdpi/ic_notification.png b/src/main/res/drawable-hdpi/ic_notification.png index c466a7b1..31c0ee1a 100644 Binary files a/src/main/res/drawable-hdpi/ic_notification.png and b/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/src/main/res/drawable-hdpi/ic_received_indicator.png b/src/main/res/drawable-hdpi/ic_received_indicator.png index b1e3f274..4d2eab56 100644 Binary files a/src/main/res/drawable-hdpi/ic_received_indicator.png and b/src/main/res/drawable-hdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_away.png b/src/main/res/drawable-hdpi/ic_send_location_away.png new file mode 100644 index 00000000..d139818b Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_dnd.png b/src/main/res/drawable-hdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..3bcbe18a Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_offline.png b/src/main/res/drawable-hdpi/ic_send_location_offline.png new file mode 100644 index 00000000..4aec18af Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_online.png b/src/main/res/drawable-hdpi/ic_send_location_online.png new file mode 100644 index 00000000..19ddc51e Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_away.png b/src/main/res/drawable-hdpi/ic_send_photo_away.png new file mode 100644 index 00000000..f6beb23c Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..2eb85679 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_offline.png b/src/main/res/drawable-hdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..046f989b Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_online.png b/src/main/res/drawable-hdpi/ic_send_photo_online.png new file mode 100644 index 00000000..3fd20d10 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_away.png b/src/main/res/drawable-hdpi/ic_send_text_away.png new file mode 100644 index 00000000..d9ef99c5 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_dnd.png b/src/main/res/drawable-hdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..706b6505 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_offline.png b/src/main/res/drawable-hdpi/ic_send_text_offline.png new file mode 100644 index 00000000..0f23fdbb Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_online.png b/src/main/res/drawable-hdpi/ic_send_text_online.png new file mode 100644 index 00000000..305f1ec2 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_away.png b/src/main/res/drawable-hdpi/ic_send_voice_away.png new file mode 100644 index 00000000..e87d9751 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..50184ee8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_offline.png b/src/main/res/drawable-hdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..68ce48b8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_online.png b/src/main/res/drawable-hdpi/ic_send_voice_online.png new file mode 100644 index 00000000..bfd7dfa7 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_away.png b/src/main/res/drawable-mdpi/ic_action_send_now_away.png deleted file mode 100644 index 0fdca901..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png deleted file mode 100644 index c0aef36c..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_offline.png b/src/main/res/drawable-mdpi/ic_action_send_now_offline.png deleted file mode 100644 index 7723f4aa..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_action_send_now_online.png b/src/main/res/drawable-mdpi/ic_action_send_now_online.png deleted file mode 100644 index 39d00ee4..00000000 Binary files a/src/main/res/drawable-mdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/ic_launcher.png b/src/main/res/drawable-mdpi/ic_launcher.png index 063ee15d..733e9615 100644 Binary files a/src/main/res/drawable-mdpi/ic_launcher.png and b/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-mdpi/ic_notification.png b/src/main/res/drawable-mdpi/ic_notification.png index fa35b7c1..aafc54f5 100644 Binary files a/src/main/res/drawable-mdpi/ic_notification.png and b/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/src/main/res/drawable-mdpi/ic_received_indicator.png b/src/main/res/drawable-mdpi/ic_received_indicator.png index 88ff1efb..2ba92b69 100644 Binary files a/src/main/res/drawable-mdpi/ic_received_indicator.png and b/src/main/res/drawable-mdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_away.png b/src/main/res/drawable-mdpi/ic_send_location_away.png new file mode 100644 index 00000000..821e80d2 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_dnd.png b/src/main/res/drawable-mdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..92e68ee3 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_offline.png b/src/main/res/drawable-mdpi/ic_send_location_offline.png new file mode 100644 index 00000000..ff11a080 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_online.png b/src/main/res/drawable-mdpi/ic_send_location_online.png new file mode 100644 index 00000000..a0eb4018 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_away.png b/src/main/res/drawable-mdpi/ic_send_photo_away.png new file mode 100644 index 00000000..d9c1f266 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..7b6700d6 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_offline.png b/src/main/res/drawable-mdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..f3e6e1fa Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_online.png b/src/main/res/drawable-mdpi/ic_send_photo_online.png new file mode 100644 index 00000000..0aaab38d Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_away.png b/src/main/res/drawable-mdpi/ic_send_text_away.png new file mode 100644 index 00000000..ddd983b5 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_dnd.png b/src/main/res/drawable-mdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..92df9d3d Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_offline.png b/src/main/res/drawable-mdpi/ic_send_text_offline.png new file mode 100644 index 00000000..72b9da27 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_online.png b/src/main/res/drawable-mdpi/ic_send_text_online.png new file mode 100644 index 00000000..86d1e330 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_away.png b/src/main/res/drawable-mdpi/ic_send_voice_away.png new file mode 100644 index 00000000..943f690f Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..ef25b1c4 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_offline.png b/src/main/res/drawable-mdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..e6b2355f Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_online.png b/src/main/res/drawable-mdpi/ic_send_voice_online.png new file mode 100644 index 00000000..bd0e1f87 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_away.png b/src/main/res/drawable-xhdpi/ic_action_send_now_away.png deleted file mode 100644 index bb999d85..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index a0bf5561..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png b/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 6da9ff7b..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_action_send_now_online.png b/src/main/res/drawable-xhdpi/ic_action_send_now_online.png deleted file mode 100644 index 348ba657..00000000 Binary files a/src/main/res/drawable-xhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/ic_launcher.png b/src/main/res/drawable-xhdpi/ic_launcher.png index fd9937f1..c9e48859 100644 Binary files a/src/main/res/drawable-xhdpi/ic_launcher.png and b/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xhdpi/ic_notification.png b/src/main/res/drawable-xhdpi/ic_notification.png index 43daff65..042d2cda 100644 Binary files a/src/main/res/drawable-xhdpi/ic_notification.png and b/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xhdpi/ic_received_indicator.png b/src/main/res/drawable-xhdpi/ic_received_indicator.png index 2c871933..cf7c2bb8 100644 Binary files a/src/main/res/drawable-xhdpi/ic_received_indicator.png and b/src/main/res/drawable-xhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_away.png b/src/main/res/drawable-xhdpi/ic_send_location_away.png new file mode 100644 index 00000000..0a5f3d54 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..90ce346c Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_offline.png b/src/main/res/drawable-xhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..114ce01b Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_online.png b/src/main/res/drawable-xhdpi/ic_send_location_online.png new file mode 100644 index 00000000..17204eea Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_away.png b/src/main/res/drawable-xhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..7ac674ea Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..2c37db74 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..6ef1e16a Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_online.png b/src/main/res/drawable-xhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..f585ef98 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_away.png b/src/main/res/drawable-xhdpi/ic_send_text_away.png new file mode 100644 index 00000000..41f223f6 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..0a749f8d Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_offline.png b/src/main/res/drawable-xhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..d0a98e5d Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_online.png b/src/main/res/drawable-xhdpi/ic_send_text_online.png new file mode 100644 index 00000000..91d240d2 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_away.png b/src/main/res/drawable-xhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..34f8ea86 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..cea4212a Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..fc4cff1f Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_online.png b/src/main/res/drawable-xhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..d2f03dd5 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png deleted file mode 100644 index 12ec4d33..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_away.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png deleted file mode 100644 index 7719f81a..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_dnd.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png deleted file mode 100644 index 18895813..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_offline.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png b/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png deleted file mode 100644 index 29bde36e..00000000 Binary files a/src/main/res/drawable-xxhdpi/ic_action_send_now_online.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/ic_launcher.png b/src/main/res/drawable-xxhdpi/ic_launcher.png index 0e06656f..e69b9c8d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_launcher.png and b/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_notification.png b/src/main/res/drawable-xxhdpi/ic_notification.png index c2ee5dec..42c62d32 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_notification.png and b/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxhdpi/ic_received_indicator.png index 039a9ef9..5d1c9b87 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_received_indicator.png and b/src/main/res/drawable-xxhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_away.png b/src/main/res/drawable-xxhdpi/ic_send_location_away.png new file mode 100644 index 00000000..4fb370ff Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..ea3d1502 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_offline.png b/src/main/res/drawable-xxhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..b4317aae Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_online.png b/src/main/res/drawable-xxhdpi/ic_send_location_online.png new file mode 100644 index 00000000..10dfed81 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_away.png b/src/main/res/drawable-xxhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..78eea39e Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..09c11a81 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..6b41c3bd Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_online.png b/src/main/res/drawable-xxhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..1c8992c5 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_away.png b/src/main/res/drawable-xxhdpi/ic_send_text_away.png new file mode 100644 index 00000000..2b2b0793 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..0d7e7053 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_offline.png b/src/main/res/drawable-xxhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..6bd9c414 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_online.png b/src/main/res/drawable-xxhdpi/ic_send_text_online.png new file mode 100644 index 00000000..cb6a2dba Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_away.png b/src/main/res/drawable-xxhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..b8b9e807 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..a5151331 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..3d58f699 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_online.png b/src/main/res/drawable-xxhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..600371eb Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_launcher.png b/src/main/res/drawable-xxxhdpi/ic_launcher.png index b6dcb0b9..668504df 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_launcher.png and b/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_notification.png b/src/main/res/drawable-xxxhdpi/ic_notification.png index ee2f3a43..c3439f1a 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_notification.png and b/src/main/res/drawable-xxxhdpi/ic_notification.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxxhdpi/ic_received_indicator.png index 86db9890..f35c8b44 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_received_indicator.png and b/src/main/res/drawable-xxxhdpi/ic_received_indicator.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_away.png b/src/main/res/drawable-xxxhdpi/ic_send_location_away.png new file mode 100644 index 00000000..0fab2554 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png new file mode 100644 index 00000000..08e2b39b Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png new file mode 100644 index 00000000..2af75cde Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_online.png b/src/main/res/drawable-xxxhdpi/ic_send_location_online.png new file mode 100644 index 00000000..2e54ef89 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_location_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png new file mode 100644 index 00000000..ba171ce1 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png new file mode 100644 index 00000000..fccb32dc Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png new file mode 100644 index 00000000..e94e930d Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png new file mode 100644 index 00000000..1bf680eb Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_photo_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_away.png b/src/main/res/drawable-xxxhdpi/ic_send_text_away.png new file mode 100644 index 00000000..afcfa89d Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png new file mode 100644 index 00000000..929a33a4 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png new file mode 100644 index 00000000..b9122e45 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_online.png b/src/main/res/drawable-xxxhdpi/ic_send_text_online.png new file mode 100644 index 00000000..abec2e0b Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_text_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png new file mode 100644 index 00000000..de1375e2 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png new file mode 100644 index 00000000..8ac667be Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png new file mode 100644 index 00000000..eec3d8f2 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png new file mode 100644 index 00000000..fcdfcb43 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_voice_online.png differ diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml index f9aae10a..5aa7dffa 100644 --- a/src/main/res/layout/fragment_conversation.xml +++ b/src/main/res/layout/fragment_conversation.xml @@ -57,7 +57,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" android:background="?android:selectableItemBackground" - android:src="@drawable/ic_action_send_now_offline" /> + android:src="@drawable/ic_send_text_offline" /> -1 + + @string/none + @string/recently_used + @string/attach_take_picture + @string/attach_record_voice + @string/send_location + + + + none + recent + photo + voice + location + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index cc7727d2..4631bd60 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1,397 +1,397 @@ - Conversations - Settings - New conversation - Manage accounts - End this conversation - Contact details - Conference details - Secure conversation - Add account - Edit name - Add to phone book - Delete from roster - Block contact - Unblock contact - Block domain - Unblock domain - Manage Accounts - Settings - Conference Details - Contact Details - Share with Conversation - Start Conversation - Choose contact - Block list - just now - 1 min ago - %d mins ago - unread Conversations - sending… - Decrypting message. Please wait… - Nickname is already in use - Admin - Owner - Moderator - Participant - Visitor - Would you like to remove %s from your roster? The conversation associated with this contact will not be removed. - Would you like to block %s from sending you messages? - Would you like to unblock %s and allow them to send you messages? - Block all contacts from %s? - Unblock all contacts from %s? - Contact blocked - Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed. - Register new account on server - Change password on server - Share with… - Start Conversation - Invite Contact - Contacts - Cancel - Set - Add - Edit - Delete - Block - Unblock - Save - OK - Conversations has crashed - By sending in stack traces you are helping the ongoing development of Conversations\nWarning: This will use your XMPP account to send the stack trace to the developer. - Send now - Never ask again - Unable to connect to account - Unable to connect to multiple accounts - Touch here to manage your accounts - Attach file - The contact is not in your roster. Would you like to add it? - Add contact - delivery failed - rejected - Preparing image for transmission - Clear history - Clear Conversation History - Do you want to delete all messages within this Conversation?\n\nWarning: This will not influence messages stored on other devices or servers. - Delete messages - End this conversations afterwards - Choose presence to contact - Send plain text message - Send OTR encrypted message - Send OpenPGP encrypted message - Your nickname has been changed - Download Image - Send unencrypted - Decryption failed. Maybe you don’t have the proper private key. - OpenKeychain - Conversations utilizes a third party app called OpenKeychain to encrypt and decrypt messages and to manage your public keys.\n\nOpenKeychain is licensed under GPLv3 and available on F-Droid and Google Play.\n\n(Please restart Conversations afterwards.) - Restart - Install - offering… - waiting… - No OpenPGP Key found - Conversations is unable to encrypt your messages because your contact is not announcing his or hers public key.\n\nPlease ask your contact to setup OpenPGP. - No OpenPGP Keys found - Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\nPlease ask your contacts to setup OpenPGP. - Encrypted message received. Touch to view and decrypt. - General - XMPP resource - The name this client identifies itself with - Accept files - Automatically accept files smaller than… - Notification Settings - Notifications - Notify when a new message arrives - Vibrate - Also vibrate when a new message arrives - Sound - Play ringtone with notification - Conference notifications - Always notify when a new conference message arrives instead of only when highlighted - Notification grace period - Disable notifications for a short time after a carbon copy was received - Advanced Options - Never send crash reports - By sending in stack traces you are helping the ongoing development of Conversations - Confirm Messages - Let your contact know when you have received and read a message - UI Options - OpenKeychain reported an error - I/O Error decrypting file - Accept - An error has occurred - Grant presence updates - Preemptively grant and ask for presence subscription for contacts you created - Subscriptions - Your account - Keys - Send presence updates - Receive presence updates - Ask for presence updates - Choose picture - Take picture - Preemptively grant subscription request - The file you selected is not an image - Error while converting the image file - File not found - General I/O error. Maybe you ran out of storage space? - The app you used to select this image did not provide us with enough permissions to read the file.\n\nUse a different file manager to choose an image - Unknown - Temporarily disabled - Online - Connecting\u2026 - Offline - Unauthorized - Server not found - No connectivity - Registration failed - Username already in use - Registration completed - Server does not support registration - Security error - Incompatible server - Plain text - OTR - OpenPGP - Edit account - Delete account - Temporarily disable - Publish avatar - Publish OpenPGP public key - Enable account - Are you sure? - If you delete your account your entire conversation history will be lost - Record voice - Jabber ID - Password - username@example.com - Confirm password - Password - Confirm password - Passwords do not match - This is not a valid Jabber ID - Out of memory. Image is too large - Do you want to add %s to your phones contact list? - online - free to chat - away - extended away - do not disturb - offline - Conference - Other Members - Server info - XEP-0313: MAM - XEP-0280: Message Carbons - XEP-0352: Client State Indication - XEP-0191: Blocking Command - XEP-0237: Roster Versioning - XEP-0198: Stream Management - XEP-0163: PEP (Avatars) - available - unavailable - Missing public key announcements - last seen just now - last seen 1 minute ago - last seen %d minutes ago - last seen 1 hour ago - last seen %d hours ago - last seen 1 day ago - last seen %d days ago - never seen - Encrypted message. Please install OpenKeychain to decrypt. - Unknown OTR fingerprint - OpenPGP encrypted messages found - Reception failed - Your fingerprint - OTR fingerprint - Verify - Decrypt - Conferences - Search - Create Contact - Join Conference - Delete Contact - View contact details - Block contact - Unblock contact - Create - The contact already exists - Join - Conference address - room@conference.example.com - Save as bookmark - Delete bookmark - This bookmark already exists - You - Edit conference subject - Conference not found - Leave - Contact added you to contact list - Add back - %s has read up to this point - Publish - Touch avatar to select picture from gallery - Please note: Everyone subscribed to your presence updates will be allowed to see this picture. - Publishing… - The server rejected your publication - Something went wrong while converting your picture - Could not save avatar to disk - (Or long press to bring back default) - Your server does not support the publication of avatars - whispered - to %s - Send private message to %s - Connect - This account already exists - Next - Current session established - Additional Information - Skip - Disable notifications - Disable notifications for this conversation - Notifications are disabled - Enable - Conference requires password - Enter password - Missing presence updates from contact - Please request presence updates from your contact first.\n\nThis will be used to determine what client(s) your contact is using. - Request now - Delete Fingerprint - Are you sure you would like to delete this fingerprint? - Ignore - Warning: Sending this without mutual presence updates could cause unexpected problems.\n\nGo to contact details to verify your presence subscriptions. - Encryption settings - Force end-to-end encryption - Always send messages encrypted (except for conferences) - Don’t save encrypted messages - Warning: This could lead to message loss - Expert options - Please be careful with these - About Conversations - Build and licensing information - - Conversations • the very last word in instant messaging. - \n\nCopyright © 2014 Daniel Gultsch - \n\nThis 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. - \n\nThis 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. - \n\nYou should have received a copy of the GNU General Public License - along with this program. If not, see https://www.gnu.org/licenses - \n\nDownload the full source code at https://github.com/siacs/Conversations - \n\n\nLibraries - \n\nhttps://www.bouncycastle.org\n(The MIT License (MIT)) - \n\nhttps://www.gnu.org/software/libidn\n(Apache License, Version 2.0) - \n\nhttps://github.com/ge0rg/MemorizingTrustManager\n(The MIT License (MIT)) - \n\nhttps://github.com/rtreffer/minidns\n(WTFPL) - \n\nhttps://github.com/open-keychain/openkeychain-api-lib\n(Apache License, Version 2.0) - \n\nhttps://github.com/jitsi/otr4j\n(LGPL-3.0) - \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) - \n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0) - \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) - \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0) - - Quiet Hours - Start time - End time - Enable quiet hours - Notifications will be silenced during quiet hours - Increase font size - Use larger font sizes across the entire app - Send button indicates status - Request message receipts - Received messages will be marked with a green tick if supported - Colorize send button to indicate contact status - Other - Conference name - Use room’s subject instead of JID to identify conferences - OTR fingerprint copied to clipboard! - You are banned from this conference - This conference is members only - You have been kicked from this conference - using account %s - Checking image on HTTP host - The image file has been deleted - You are not connected. Try again later - Check image file size - Message options - Copy text - Copy original URL - Send again - Image URL - Message text - URL copied to clipboard - Message copied to clipboard - Image transmission failed - Scan QR code - Show QR code - Show block list - Account details - Verify OTR - Remote Fingerprint - scan - (or touch phones) - Socialist Millionaire Protocol - Hint or Question - Shared Secret - Confirm - In progress - Respond - Failed - Secrets do not match - Try again - Finish - Verified! - Contact requested SMP verification - No valid OTR session has been found! - Conversations - Keep service in foreground - Prevents the operating system from killing your connection - Choose file - Receiving %1$s (%2$d%% completed) - Download %s - file - Open %s - sending (%1$d%% completed) - Preparing file for transmission - %s offered for download - Cancel transmission - file transmission failed - The file has been deleted - No application found to open file - Could not verify fingerprint - Manually verify - Are you sure that you want to verify your contacts OTR fingerprint? - Show dynamic tags - Display read-only tags underneath contacts - Enable notifications - Create conference with… - No conference server found - Conference creation failed! - Conference created! - Secret accepted! - Reset - Account avatar - Copy OTR fingerprint to clipboard - Fetching history from server - No more history on server - Updating… - Password changed! - Could not change password - Send a message to start an encrypted chat - Ask question - If you and your contact have a secret in common that no one else knows (like an inside joke or simply what you had for lunch the last time you met) you can use that secret to verify each other’s fingerprints.\n\nYou provide a hint or a question for your contact who will respond with a case-sensitive answer. - Your contact would like to verify your fingerprint by challenging you with a shared secret. Your contact provided the following hint or question for that secret. - Your hint should not be empty - Your shared secret can not be empty - Carefully compare the fingerprint shown below with the fingerprint of your contact.\nYou can use any trusted form of communication like an encrypted e-mail or a telephone call to exchange those. + Conversations + Settings + New conversation + Manage accounts + End this conversation + Contact details + Conference details + Secure conversation + Add account + Edit name + Add to phone book + Delete from roster + Block contact + Unblock contact + Block domain + Unblock domain + Manage Accounts + Settings + Conference Details + Contact Details + Share with Conversation + Start Conversation + Choose contact + Block list + just now + 1 min ago + %d mins ago + unread Conversations + sending… + Decrypting message. Please wait… + Nickname is already in use + Admin + Owner + Moderator + Participant + Visitor + Would you like to remove %s from your roster? The conversation associated with this contact will not be removed. + Would you like to block %s from sending you messages? + Would you like to unblock %s and allow them to send you messages? + Block all contacts from %s? + Unblock all contacts from %s? + Contact blocked + Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed. + Register new account on server + Change password on server + Share with… + Start Conversation + Invite Contact + Contacts + Cancel + Set + Add + Edit + Delete + Block + Unblock + Save + OK + Conversations has crashed + By sending in stack traces you are helping the ongoing development of Conversations\nWarning: This will use your XMPP account to send the stack trace to the developer. + Send now + Never ask again + Unable to connect to account + Unable to connect to multiple accounts + Touch here to manage your accounts + Attach file + The contact is not in your roster. Would you like to add it? + Add contact + delivery failed + rejected + Preparing image for transmission + Clear history + Clear Conversation History + Do you want to delete all messages within this Conversation?\n\nWarning: This will not influence messages stored on other devices or servers. + Delete messages + End this conversations afterwards + Choose presence to contact + Send plain text message + Send OTR encrypted message + Send OpenPGP encrypted message + Your nickname has been changed + Download Image + Send unencrypted + Decryption failed. Maybe you don’t have the proper private key. + OpenKeychain + Conversations utilizes a third party app called OpenKeychain to encrypt and decrypt messages and to manage your public keys.\n\nOpenKeychain is licensed under GPLv3 and available on F-Droid and Google Play.\n\n(Please restart Conversations afterwards.) + Restart + Install + offering… + waiting… + No OpenPGP Key found + Conversations is unable to encrypt your messages because your contact is not announcing his or hers public key.\n\nPlease ask your contact to setup OpenPGP. + No OpenPGP Keys found + Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\nPlease ask your contacts to setup OpenPGP. + Encrypted message received. Touch to view and decrypt. + General + XMPP resource + The name this client identifies itself with + Accept files + Automatically accept files smaller than… + Notification Settings + Notifications + Notify when a new message arrives + Vibrate + Also vibrate when a new message arrives + Sound + Play ringtone with notification + Conference notifications + Always notify when a new conference message arrives instead of only when highlighted + Notification grace period + Disable notifications for a short time after a carbon copy was received + Advanced Options + Never send crash reports + By sending in stack traces you are helping the ongoing development of Conversations + Confirm Messages + Let your contact know when you have received and read a message + UI Options + OpenKeychain reported an error + I/O Error decrypting file + Accept + An error has occurred + Grant presence updates + Preemptively grant and ask for presence subscription for contacts you created + Subscriptions + Your account + Keys + Send presence updates + Receive presence updates + Ask for presence updates + Choose picture + Take picture + Preemptively grant subscription request + The file you selected is not an image + Error while converting the image file + File not found + General I/O error. Maybe you ran out of storage space? + The app you used to select this image did not provide us with enough permissions to read the file.\n\nUse a different file manager to choose an image + Unknown + Temporarily disabled + Online + Connecting\u2026 + Offline + Unauthorized + Server not found + No connectivity + Registration failed + Username already in use + Registration completed + Server does not support registration + Security error + Incompatible server + Plain text + OTR + OpenPGP + Edit account + Delete account + Temporarily disable + Publish avatar + Publish OpenPGP public key + Enable account + Are you sure? + If you delete your account your entire conversation history will be lost + Record voice + Jabber ID + Password + username@example.com + Confirm password + Password + Confirm password + Passwords do not match + This is not a valid Jabber ID + Out of memory. Image is too large + Do you want to add %s to your phones contact list? + online + free to chat + away + extended away + do not disturb + offline + Conference + Other Members + Server info + XEP-0313: MAM + XEP-0280: Message Carbons + XEP-0352: Client State Indication + XEP-0191: Blocking Command + XEP-0237: Roster Versioning + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) + available + unavailable + Missing public key announcements + last seen just now + last seen 1 minute ago + last seen %d minutes ago + last seen 1 hour ago + last seen %d hours ago + last seen 1 day ago + last seen %d days ago + never seen + Encrypted message. Please install OpenKeychain to decrypt. + Unknown OTR fingerprint + OpenPGP encrypted messages found + Reception failed + Your fingerprint + OTR fingerprint + Verify + Decrypt + Conferences + Search + Create Contact + Join Conference + Delete Contact + View contact details + Block contact + Unblock contact + Create + The contact already exists + Join + Conference address + room@conference.example.com + Save as bookmark + Delete bookmark + This bookmark already exists + You + Edit conference subject + Conference not found + Leave + Contact added you to contact list + Add back + %s has read up to this point + Publish + Touch avatar to select picture from gallery + Please note: Everyone subscribed to your presence updates will be allowed to see this picture. + Publishing… + The server rejected your publication + Something went wrong while converting your picture + Could not save avatar to disk + (Or long press to bring back default) + Your server does not support the publication of avatars + whispered + to %s + Send private message to %s + Connect + This account already exists + Next + Current session established + Additional Information + Skip + Disable notifications + Disable notifications for this conversation + Notifications are disabled + Enable + Conference requires password + Enter password + Missing presence updates from contact + Please request presence updates from your contact first.\n\nThis will be used to determine what client(s) your contact is using. + Request now + Delete Fingerprint + Are you sure you would like to delete this fingerprint? + Ignore + Warning: Sending this without mutual presence updates could cause unexpected problems.\n\nGo to contact details to verify your presence subscriptions. + Encryption settings + Force end-to-end encryption + Always send messages encrypted (except for conferences) + Don’t save encrypted messages + Warning: This could lead to message loss + Expert options + Please be careful with these + About Conversations + Build and licensing information + + Conversations • the very last word in instant messaging. + \n\nCopyright © 2014 Daniel Gultsch + \n\nThis 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. + \n\nThis 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. + \n\nYou should have received a copy of the GNU General Public License + along with this program. If not, see https://www.gnu.org/licenses + \n\nDownload the full source code at https://github.com/siacs/Conversations + \n\n\nLibraries + \n\nhttps://www.bouncycastle.org\n(The MIT License (MIT)) + \n\nhttps://www.gnu.org/software/libidn\n(Apache License, Version 2.0) + \n\nhttps://github.com/ge0rg/MemorizingTrustManager\n(The MIT License (MIT)) + \n\nhttps://github.com/rtreffer/minidns\n(WTFPL) + \n\nhttps://github.com/open-keychain/openkeychain-api-lib\n(Apache License, Version 2.0) + \n\nhttps://github.com/jitsi/otr4j\n(LGPL-3.0) + \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) + \n\nhttps://github.com/zxing/zxing\n(Apache License, Version 2.0) + \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) + \n\nhttps://github.com/timroes/EnhancedListView\n(Apache License, Version 2.0) + + Quiet Hours + Start time + End time + Enable quiet hours + Notifications will be silenced during quiet hours + Increase font size + Use larger font sizes across the entire app + Send button indicates status + Request message receipts + Received messages will be marked with a green tick if supported + Colorize send button to indicate contact status + Other + Conference name + Use room’s subject instead of JID to identify conferences + OTR fingerprint copied to clipboard! + You are banned from this conference + This conference is members only + You have been kicked from this conference + using account %s + Checking image on HTTP host + The image file has been deleted + You are not connected. Try again later + Check image file size + Message options + Copy text + Copy original URL + Send again + Image URL + Message text + URL copied to clipboard + Message copied to clipboard + Image transmission failed + Scan QR code + Show QR code + Show block list + Account details + Verify OTR + Remote Fingerprint + scan + (or touch phones) + Socialist Millionaire Protocol + Hint or Question + Shared Secret + Confirm + In progress + Respond + Failed + Secrets do not match + Try again + Finish + Verified! + Contact requested SMP verification + No valid OTR session has been found! + Conversations + Keep service in foreground + Prevents the operating system from killing your connection + Choose file + Receiving %1$s (%2$d%% completed) + Download %s + file + Open %s + sending (%1$d%% completed) + Preparing file for transmission + %s offered for download + Cancel transmission + file transmission failed + The file has been deleted + No application found to open file + Could not verify fingerprint + Manually verify + Are you sure that you want to verify your contacts OTR fingerprint? + Show dynamic tags + Display read-only tags underneath contacts + Enable notifications + Create conference with… + No conference server found + Conference creation failed! + Conference created! + Secret accepted! + Reset + Account avatar + Copy OTR fingerprint to clipboard + Fetching history from server + No more history on server + Updating… + Password changed! + Could not change password + Send a message to start an encrypted chat + Ask question + If you and your contact have a secret in common that no one else knows (like an inside joke or simply what you had for lunch the last time you met) you can use that secret to verify each other’s fingerprints.\n\nYou provide a hint or a question for your contact who will respond with a case-sensitive answer. + Your contact would like to verify your fingerprint by challenging you with a shared secret. Your contact provided the following hint or question for that secret. + Your hint should not be empty + Your shared secret can not be empty + Carefully compare the fingerprint shown below with the fingerprint of your contact.\nYou can use any trusted form of communication like an encrypted e-mail or a telephone call to exchange those. Change password Current password New password @@ -442,19 +442,19 @@ Disable foreground service Touch to open Conversations Avatar has been published! - Sending %s - Offering %s - Hide offline - Disable Account - %s is typing... - %s has stopped typing - Typing notifications - Let your contact know when you are writing a new message - Send location - Show location - No application found to display location - Location - Received location + Sending %s + Offering %s + Hide offline + Disable Account + %s is typing... + %s has stopped typing + Typing notifications + Let your contact know when you are writing a new message + Send location + Show location + No application found to display location + Location + Received location Conversation closed Left conference Certificate options @@ -474,4 +474,9 @@ Select %d contact Select %d contacts + Replace send button with quick action + Quick Action + None + Most recently used + Choose quick action diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 417e60a4..5b7d6904 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -105,6 +105,14 @@ android:key="send_button_status" android:summary="@string/pref_use_send_button_to_indicate_status_summary" android:title="@string/pref_use_send_button_to_indicate_status" /> + Date: Sat, 2 May 2015 11:58:19 +0200 Subject: shut up linter. fixed build --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a4062ec3..7b8742c9 100644 --- a/build.gradle +++ b/build.gradle @@ -92,7 +92,7 @@ android { } lintOptions { - disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage' + disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage', 'MissingQuantity' } subprojects { -- cgit v1.2.3 From 48e8e0f1fc1afd8f50e4ac17f235f9f587f637dc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:00:27 +0200 Subject: version bump to 1.4.0-alpha (in development) --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 7b8742c9..610b8818 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 60 - versionName "1.3.0" + versionCode 61 + versionName "1.4.0-alpha" } compileOptions { -- cgit v1.2.3 From c4bfffe6a9027d041cccf610b448cb6c1367c83d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 2 May 2015 12:10:56 +0200 Subject: mark account with incompatible server when no sasl mechansim could be found --- .../siacs/conversations/xmpp/XmppConnection.java | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0b6bb15b..a2b58a14 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -581,26 +581,31 @@ public class XmppConnection implements Runnable { } else if (mechanisms.contains("DIGEST-MD5")) { saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); } - final JSONObject keys = account.getKeys(); - try { - if (keys.has(Account.PINNED_MECHANISM_KEY) && - keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority() ) { - Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + - " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + - ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + - "). Possible downgrade attack?"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); - } - } catch (final JSONException e) { - Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); - } - Log.d(Config.LOGTAG,account.getJid().toString()+": Authenticating with " + saslMechanism.getMechanism()); - auth.setAttribute("mechanism", saslMechanism.getMechanism()); - if (!saslMechanism.getClientFirstMessage().isEmpty()) { - auth.setContent(saslMechanism.getClientFirstMessage()); + if (saslMechanism != null) { + final JSONObject keys = account.getKeys(); + try { + if (keys.has(Account.PINNED_MECHANISM_KEY) && + keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { + Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + + " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + + "). Possible downgrade attack?"); + disconnect(true); + changeStatus(Account.State.SECURITY_ERROR); + } + } catch (final JSONException e) { + Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); + } + Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); + auth.setAttribute("mechanism", saslMechanism.getMechanism()); + if (!saslMechanism.getClientFirstMessage().isEmpty()) { + auth.setContent(saslMechanism.getClientFirstMessage()); + } + tagWriter.writeElement(auth); + } else { + disconnect(true); + changeStatus(Account.State.INCOMPATIBLE_SERVER); } - tagWriter.writeElement(auth); } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { -- cgit v1.2.3 From 43db9cdf4b300183cfd58ad9c7b3ad57ee63ad31 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 3 May 2015 09:30:30 +0200 Subject: turn send button in cancel button while in whisper mode --- art/ic_send_cancel_away.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_dnd.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_offline.svg | 54 +++++++++++++++++++++ art/ic_send_cancel_online.svg | 54 +++++++++++++++++++++ art/render.rb | 4 ++ .../conversations/ui/ConversationFragment.java | 42 +++++++++++----- src/main/res/drawable-hdpi/ic_send_cancel_away.png | Bin 0 -> 1396 bytes src/main/res/drawable-hdpi/ic_send_cancel_dnd.png | Bin 0 -> 1559 bytes .../res/drawable-hdpi/ic_send_cancel_offline.png | Bin 0 -> 1206 bytes .../res/drawable-hdpi/ic_send_cancel_online.png | Bin 0 -> 1531 bytes src/main/res/drawable-mdpi/ic_send_cancel_away.png | Bin 0 -> 901 bytes src/main/res/drawable-mdpi/ic_send_cancel_dnd.png | Bin 0 -> 1040 bytes .../res/drawable-mdpi/ic_send_cancel_offline.png | Bin 0 -> 837 bytes .../res/drawable-mdpi/ic_send_cancel_online.png | Bin 0 -> 1052 bytes .../res/drawable-xhdpi/ic_send_cancel_away.png | Bin 0 -> 1724 bytes src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png | Bin 0 -> 1940 bytes .../res/drawable-xhdpi/ic_send_cancel_offline.png | Bin 0 -> 1519 bytes .../res/drawable-xhdpi/ic_send_cancel_online.png | Bin 0 -> 1978 bytes .../res/drawable-xxhdpi/ic_send_cancel_away.png | Bin 0 -> 2583 bytes .../res/drawable-xxhdpi/ic_send_cancel_dnd.png | Bin 0 -> 2911 bytes .../res/drawable-xxhdpi/ic_send_cancel_offline.png | Bin 0 -> 2290 bytes .../res/drawable-xxhdpi/ic_send_cancel_online.png | Bin 0 -> 2998 bytes .../res/drawable-xxxhdpi/ic_send_cancel_away.png | Bin 0 -> 3377 bytes .../res/drawable-xxxhdpi/ic_send_cancel_dnd.png | Bin 0 -> 3791 bytes .../drawable-xxxhdpi/ic_send_cancel_offline.png | Bin 0 -> 2956 bytes .../res/drawable-xxxhdpi/ic_send_cancel_online.png | Bin 0 -> 3835 bytes 26 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 art/ic_send_cancel_away.svg create mode 100644 art/ic_send_cancel_dnd.svg create mode 100644 art/ic_send_cancel_offline.svg create mode 100644 art/ic_send_cancel_online.svg create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-hdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-mdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xhdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xxhdpi/ic_send_cancel_online.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png diff --git a/art/ic_send_cancel_away.svg b/art/ic_send_cancel_away.svg new file mode 100644 index 00000000..1ee9c40f --- /dev/null +++ b/art/ic_send_cancel_away.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_dnd.svg b/art/ic_send_cancel_dnd.svg new file mode 100644 index 00000000..54e02a91 --- /dev/null +++ b/art/ic_send_cancel_dnd.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_offline.svg b/art/ic_send_cancel_offline.svg new file mode 100644 index 00000000..b88ade09 --- /dev/null +++ b/art/ic_send_cancel_offline.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/ic_send_cancel_online.svg b/art/ic_send_cancel_online.svg new file mode 100644 index 00000000..40946af6 --- /dev/null +++ b/art/ic_send_cancel_online.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 32d06f8f..ad53b1f4 100755 --- a/art/render.rb +++ b/art/render.rb @@ -26,6 +26,10 @@ images = { 'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36], 'ic_send_voice_away.svg' => ['ic_send_voice_away', 36], 'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36], + 'ic_send_cancel_online.svg' => ['ic_send_cancel_online', 36], + 'ic_send_cancel_offline.svg' => ['ic_send_cancel_offline', 36], + 'ic_send_cancel_away.svg' => ['ic_send_cancel_away', 36], + 'ic_send_cancel_dnd.svg' => ['ic_send_cancel_dnd', 36], } images.each do |source, result| resolutions.each do |name, factor| diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 37ae00a3..6b11d310 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -245,6 +245,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa case RECORD_VOICE: activity.attachFile(ConversationActivity.ATTACHMENT_CHOICE_RECORD_VOICE); break; + case CANCEL: + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setNextCounterpart(null); + updateChatMsgHint(); + updateSendButton(); + } + break; default: sendMessage(); } @@ -257,8 +264,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onClick(View v) { - Intent intent = new Intent(getActivity(), - ConferenceDetailsActivity.class); + Intent intent = new Intent(getActivity(), ConferenceDetailsActivity.class); intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); intent.putExtra("uuid", conversation.getUuid()); startActivity(intent); @@ -271,13 +277,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (this.conversation == null) { return; } - if (mEditMessage.getText().length() < 1) { - if (this.conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setNextCounterpart(null); - updateChatMsgHint(); - } - return; - } Message message = new Message(conversation, mEditMessage.getText() .toString(), conversation.getNextEncryption(activity .forceEncryption())); @@ -558,6 +557,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa this.mEditMessage.setText(""); this.conversation.setNextCounterpart(counterpart); updateChatMsgHint(); + updateSendButton(); } protected void highlightInConference(String nick) { @@ -808,7 +808,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateChatMsgHint(); } - enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE} + enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE, CANCEL} private int getSendButtonImageResource(SendButtonAction action, int status) { switch (action) { @@ -864,6 +864,19 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa default: return R.drawable.ic_send_location_offline; } + case CANCEL: + switch (status) { + case Presences.CHAT: + case Presences.ONLINE: + return R.drawable.ic_send_cancel_online; + case Presences.AWAY: + return R.drawable.ic_send_cancel_away; + case Presences.XA: + case Presences.DND: + return R.drawable.ic_send_cancel_dnd; + default: + return R.drawable.ic_send_cancel_offline; + } } return R.drawable.ic_send_text_offline; } @@ -872,10 +885,15 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa final Conversation c = this.conversation; final SendButtonAction action; final int status; + final boolean empty = this.mEditMessage == null || this.mEditMessage.getText().length() == 0; if (c.getMode() == Conversation.MODE_MULTI) { - action = SendButtonAction.TEXT; + if (empty && c.getNextCounterpart() != null) { + action = SendButtonAction.CANCEL; + } else { + action = SendButtonAction.TEXT; + } } else { - if (this.mEditMessage == null || this.mEditMessage.getText().length() == 0) { + if (empty) { String setting = activity.getPreferences().getString("quick_action","recent"); if (setting.equals("recent")) { setting = activity.getPreferences().getString("recently_used_quick_action","text"); diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_away.png b/src/main/res/drawable-hdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..9525c040 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..cbfd8e76 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_offline.png b/src/main/res/drawable-hdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..2cb4f4f3 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_online.png b/src/main/res/drawable-hdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..cb3bc3b5 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_away.png b/src/main/res/drawable-mdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..bbc86b45 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..e4fa38a3 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_offline.png b/src/main/res/drawable-mdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..604dfefa Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_online.png b/src/main/res/drawable-mdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..1b0d1811 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..44b5f096 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..276ad024 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..53a9ac90 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..23a5f263 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..07113f02 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..93fbc44d Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..10412fab Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..6fa18239 Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_send_cancel_online.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png new file mode 100644 index 00000000..a9340a88 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_away.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png new file mode 100644 index 00000000..02ab1d0f Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png new file mode 100644 index 00000000..abd3af2c Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_offline.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png new file mode 100644 index 00000000..80be8edf Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_online.png differ -- cgit v1.2.3 From d15da64c5df63584d55a994d568345059a1f1c20 Mon Sep 17 00:00:00 2001 From: Alexander Groshev Date: Sun, 3 May 2015 20:53:27 +0300 Subject: Fix typos in URL to the project --- src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java index 526005f3..c40c6d05 100644 --- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java @@ -49,7 +49,7 @@ public class PresenceGenerator extends AbstractGenerator { Element cap = packet.addChild("c", "http://jabber.org/protocol/caps"); cap.setAttribute("hash", "sha-1"); - cap.setAttribute("node", "http://conversions.im"); + cap.setAttribute("node", "http://conversations.im"); cap.setAttribute("ver", capHash); } return packet; @@ -61,4 +61,4 @@ public class PresenceGenerator extends AbstractGenerator { packet.setAttribute("type","unavailable"); return packet; } -} \ No newline at end of file +} -- cgit v1.2.3 From 2582ece2105f98a7a20d72d8c8dc70772a48286f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 04:38:12 +0200 Subject: open market if share location plugin isn't installed --- .../eu/siacs/conversations/ui/ConversationActivity.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a76efbc3..349d8ffe 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -409,6 +409,7 @@ public class ConversationActivity extends XmppActivity public void onPresenceSelected() { Intent intent = new Intent(); boolean chooser = false; + String fallbackPackageId = null; switch (attachmentChoice) { case ATTACHMENT_CHOICE_CHOOSE_IMAGE: intent.setAction(Intent.ACTION_GET_CONTENT); @@ -436,6 +437,7 @@ public class ConversationActivity extends XmppActivity break; case ATTACHMENT_CHOICE_LOCATION: intent.setAction("eu.siacs.conversations.location.request"); + fallbackPackageId = "eu.siacs.conversations.sharelocation"; break; } if (intent.resolveActivity(getPackageManager()) != null) { @@ -446,12 +448,25 @@ public class ConversationActivity extends XmppActivity } else { startActivityForResult(intent, attachmentChoice); } + } else if (fallbackPackageId != null) { + startActivity(getInstallApkIntent(fallbackPackageId)); } } }); } } + private Intent getInstallApkIntent(final String packageId) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("market://details?id="+packageId)); + if (intent.resolveActivity(getPackageManager()) != null) { + return intent; + } else { + intent.setData(Uri.parse("http://play.google.com/store/apps/details?id="+packageId)); + return intent; + } + } + public void attachFile(final int attachmentChoice) { switch (attachmentChoice) { case ATTACHMENT_CHOICE_LOCATION: -- cgit v1.2.3 From 32593cff87e913522078bf41ac9c3bdd36e61801 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:07:59 +0200 Subject: updated contributor list in README.md * added BrianBlade to list * linked Pull Requests for each Contributor --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5519e47f..e7221eab 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,13 @@ run your own XMPP server for you and your friends. These XEP's are: (In order of appearance) -* [Rene Treffer](https://github.com/rtreffer) -* [Andreas Straub](https://github.com/strb) -* [Alethea Butler](https://github.com/alethea) -* [M. Dietrich](https://github.com/emdete) -* [betheg](https://github.com/betheg) -* [Sam Whited](https://github.com/SamWhited) +* [Rene Treffer](https://github.com/rtreffer) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Artreffer+is%3Amerged)) +* [Andreas Straub](https://github.com/strb) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Astrb+is%3Amerged)) +* [Alethea Butler](https://github.com/alethea) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Aalethea+is%3Amerged)) +* [M. Dietrich](https://github.com/emdete) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Aemdete+is%3Amerged)) +* [betheg](https://github.com/betheg) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Abetheg+is%3Amerged)) +* [Sam Whited](https://github.com/SamWhited) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3ASamWhited+is%3Amerged)) +* [BrianBlade](https://github.com/BrianBlade) ([PRs](https://github.com/siacs/Conversations/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3ABrianBlade+is%3Amerged)) #### Logo * [Ilia Rostovtsev](https://github.com/qooob) (Progress) -- cgit v1.2.3 From 768f1ef237a0b6d8f1577add3cb17fc2c4dea287 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:40:41 +0200 Subject: update build tools and target api --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 610b8818..b312725e 100644 --- a/build.gradle +++ b/build.gradle @@ -38,8 +38,8 @@ dependencies { } android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" + compileSdkVersion 22 + buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 14 -- cgit v1.2.3 From e388c75452788160501735a965ada9003e2a7dcb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 05:49:28 +0200 Subject: update travis config --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f147a61..a2959e0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ android: components: - platform-tools - tools + - build-tools-22.0.1 - build-tools-21.1.2 - build-tools-19.1.0 - - android-21 + - android-22 - extra-android-m2repository -- cgit v1.2.3 From 61fd5d669651042c553f9782492d7d2c4035a54f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 May 2015 09:54:10 +0200 Subject: clean up in attachment chooser code. fixed #1168 --- .../conversations/ui/ConversationActivity.java | 102 ++++++++++----------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 349d8ffe..b11ff002 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -398,61 +398,61 @@ public class ConversationActivity extends XmppActivity } private void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) { - if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) { - getSelectedConversation().setNextCounterpart(null); - Intent intent = new Intent("eu.siacs.conversations.location.request"); - startActivityForResult(intent,attachmentChoice); - } else { - selectPresence(getSelectedConversation(), new OnPresenceSelected() { + final OnPresenceSelected callback = new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - Intent intent = new Intent(); - boolean chooser = false; - String fallbackPackageId = null; - switch (attachmentChoice) { - case ATTACHMENT_CHOICE_CHOOSE_IMAGE: - intent.setAction(Intent.ACTION_GET_CONTENT); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); - } - intent.setType("image/*"); - chooser = true; - break; - case ATTACHMENT_CHOICE_TAKE_PHOTO: - Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri(); - intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); - mPendingImageUris.clear(); - mPendingImageUris.add(uri); - break; - case ATTACHMENT_CHOICE_CHOOSE_FILE: - chooser = true; - intent.setType("*/*"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setAction(Intent.ACTION_GET_CONTENT); - break; - case ATTACHMENT_CHOICE_RECORD_VOICE: - intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); - break; - case ATTACHMENT_CHOICE_LOCATION: - intent.setAction("eu.siacs.conversations.location.request"); - fallbackPackageId = "eu.siacs.conversations.sharelocation"; - break; - } - if (intent.resolveActivity(getPackageManager()) != null) { - if (chooser) { - startActivityForResult( - Intent.createChooser(intent, getString(R.string.perform_action_with)), - attachmentChoice); - } else { - startActivityForResult(intent, attachmentChoice); + @Override + public void onPresenceSelected() { + Intent intent = new Intent(); + boolean chooser = false; + String fallbackPackageId = null; + switch (attachmentChoice) { + case ATTACHMENT_CHOICE_CHOOSE_IMAGE: + intent.setAction(Intent.ACTION_GET_CONTENT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true); } - } else if (fallbackPackageId != null) { - startActivity(getInstallApkIntent(fallbackPackageId)); + intent.setType("image/*"); + chooser = true; + break; + case ATTACHMENT_CHOICE_TAKE_PHOTO: + Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri(); + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); + mPendingImageUris.clear(); + mPendingImageUris.add(uri); + break; + case ATTACHMENT_CHOICE_CHOOSE_FILE: + chooser = true; + intent.setType("*/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setAction(Intent.ACTION_GET_CONTENT); + break; + case ATTACHMENT_CHOICE_RECORD_VOICE: + intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + break; + case ATTACHMENT_CHOICE_LOCATION: + intent.setAction("eu.siacs.conversations.location.request"); + fallbackPackageId = "eu.siacs.conversations.sharelocation"; + break; + } + if (intent.resolveActivity(getPackageManager()) != null) { + if (chooser) { + startActivityForResult( + Intent.createChooser(intent, getString(R.string.perform_action_with)), + attachmentChoice); + } else { + startActivityForResult(intent, attachmentChoice); } + } else if (fallbackPackageId != null) { + startActivity(getInstallApkIntent(fallbackPackageId)); } - }); + } + }; + if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) { + getSelectedConversation().setNextCounterpart(null); + callback.onPresenceSelected(); + } else { + selectPresence(getSelectedConversation(),callback); } } -- cgit v1.2.3 From e6aa604aded25c304816164624b94bb8abe3d69f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 06:10:47 +0200 Subject: enabled sm logging by default at least for development branch --- src/main/java/eu/siacs/conversations/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 5cca6c0b..5bf320a1 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -28,7 +28,7 @@ public final class Config { public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance - public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts + public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; -- cgit v1.2.3 From 5136bf9832b9a7aeb59926b42fe6a6632452c1ef Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 06:17:34 +0200 Subject: r/o support for vcard avatars. pep avatars will be prefered --- .../eu/siacs/conversations/entities/Contact.java | 26 ++++++++--- .../siacs/conversations/generator/IqGenerator.java | 9 +++- .../siacs/conversations/parser/MessageParser.java | 2 +- .../siacs/conversations/parser/PresenceParser.java | 15 ++++++ .../services/XmppConnectionService.java | 53 ++++++++++++++++++---- .../eu/siacs/conversations/xmpp/pep/Avatar.java | 50 ++++++++++++++++---- 6 files changed, 127 insertions(+), 28 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index cef03ebe..4ad105b1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -15,6 +15,7 @@ import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.pep.Avatar; public class Contact implements ListItem, Blockable { public static final String TABLENAME = "contacts"; @@ -40,11 +41,11 @@ public class Contact implements ListItem, Blockable { protected int subscription = 0; protected String systemAccount; protected String photoUri; - protected String avatar; protected JSONObject keys = new JSONObject(); protected JSONArray groups = new JSONArray(); protected Presences presences = new Presences(); protected Account account; + protected Avatar avatar; public Contact(final String account, final String systemName, final String serverName, final Jid jid, final int subscription, final String photoUri, @@ -61,7 +62,11 @@ public class Contact implements ListItem, Blockable { } catch (JSONException e) { this.keys = new JSONObject(); } - this.avatar = avatar; + if (avatar != null) { + this.avatar = new Avatar(); + this.avatar.sha1sum = avatar; + this.avatar.origin = Avatar.Origin.VCARD; //always assume worst + } try { this.groups = (groups == null ? new JSONArray() : new JSONArray(groups)); } catch (JSONException e) { @@ -187,7 +192,7 @@ public class Contact implements ListItem, Blockable { values.put(SYSTEMACCOUNT, systemAccount); values.put(PHOTOURI, photoUri); values.put(KEYS, keys.toString()); - values.put(AVATAR, avatar); + values.put(AVATAR, avatar == null ? null : avatar.getFilename()); values.put(LAST_PRESENCE, lastseen.presence); values.put(LAST_TIME, lastseen.time); values.put(GROUPS, groups.toString()); @@ -411,17 +416,20 @@ public class Contact implements ListItem, Blockable { return getJid().toDomainJid(); } - public boolean setAvatar(String filename) { - if (this.avatar != null && this.avatar.equals(filename)) { + public boolean setAvatar(Avatar avatar) { + if (this.avatar != null && this.avatar.equals(avatar)) { return false; } else { - this.avatar = filename; + if (this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) { + return false; + } + this.avatar = avatar; return true; } } public String getAvatar() { - return this.avatar; + return avatar == null ? null : avatar.getFilename(); } public boolean deleteOtrFingerprint(String fingerprint) { @@ -478,6 +486,10 @@ public class Contact implements ListItem, Blockable { } } + public boolean isSelf() { + return account.getJid().toBareJid().equals(getJid().toBareJid()); + } + public static class Lastseen { public long time; public String presence; diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 6bc629b5..d7366daa 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -91,7 +91,7 @@ public class IqGenerator extends AbstractGenerator { return publish("urn:xmpp:avatar:metadata", item); } - public IqPacket retrieveAvatar(final Avatar avatar) { + public IqPacket retrievePepAvatar(final Avatar avatar) { final Element item = new Element("item"); item.setAttribute("id", avatar.sha1sum); final IqPacket packet = retrieve("urn:xmpp:avatar:data", item); @@ -99,6 +99,13 @@ public class IqGenerator extends AbstractGenerator { return packet; } + public IqPacket retrieveVcardAvatar(final Avatar avatar) { + final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); + packet.setTo(avatar.owner); + packet.addChild("vCard","vcard-temp"); + return packet; + } + public IqPacket retrieveAvatarMetaData(final Jid to) { final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null); if (to != null) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 76d01468..7870fdbf 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -494,7 +494,7 @@ public class MessageParser extends AbstractParser implements } else { Contact contact = account.getRoster().getContact( from); - contact.setAvatar(avatar.getFilename()); + contact.setAvatar(avatar); mXmppConnectionService.getAvatarService().clear( contact); mXmppConnectionService.updateConversationUi(); diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 7505b091..f7872210 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -13,6 +13,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; public class PresenceParser extends AbstractParser implements @@ -101,6 +102,20 @@ public class PresenceParser extends AbstractParser implements if (nick != null) { contact.setPresenceName(nick.getContent()); } + Element x = packet.findChild("x","vcard-temp:x:update"); + Avatar avatar = Avatar.parsePresence(x); + if (avatar != null && !contact.isSelf()) { + avatar.owner = from.toBareJid(); + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + if (contact.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(contact); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateRosterUi(); + } + } else { + mXmppConnectionService.fetchAvatar(account,avatar); + } + } mXmppConnectionService.updateRosterUi(); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ec0b3f92..9cee3538 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1893,9 +1893,19 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchAvatar(account, avatar, null); } - public void fetchAvatar(Account account, final Avatar avatar, - final UiCallback callback) { - IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); + public void fetchAvatar(Account account, final Avatar avatar, final UiCallback callback) { + switch (avatar.origin) { + case PEP: + fetchAvatarPep(account,avatar,callback); + break; + case VCARD: + fetchAvatarVcard(account, avatar, callback); + break; + } + } + + private void fetchAvatarPep(Account account, final Avatar avatar, final UiCallback callback) { + IqPacket packet = this.mIqGenerator.retrievePepAvatar(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @Override @@ -1916,7 +1926,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { Contact contact = account.getRoster() .getContact(avatar.owner); - contact.setAvatar(avatar.getFilename()); + contact.setAvatar(avatar); getAvatarService().clear(contact); updateConversationUi(); updateRosterUi(); @@ -1925,8 +1935,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.success(avatar); } Log.d(Config.LOGTAG, account.getJid().toBareJid() - + ": succesfully fetched avatar for " - + avatar.owner); + + ": succesfuly fetched pep avatar for " + avatar.owner); return; } } else { @@ -1949,8 +1958,34 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - public void checkForAvatar(Account account, - final UiCallback callback) { + private void fetchAvatarVcard(final Account account, final Avatar avatar, final UiCallback callback) { + IqPacket packet = this.mIqGenerator.retrieveVcardAvatar(avatar); + this.sendIqPacket(account,packet,new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element vCard = packet.findChild("vCard","vcard-temp"); + Element photo = vCard != null ? vCard.findChild("PHOTO") : null; + Element binval = photo != null ? photo.findChild("BINVAL") : null; + if (binval != null) { + avatar.image = binval.getContent(); + if (getFileBackend().save(avatar)) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + + ": successfully fetched vCard avatar for " + avatar.owner); + Contact contact = account.getRoster() + .getContact(avatar.owner); + contact.setAvatar(avatar); + getAvatarService().clear(contact); + updateConversationUi(); + updateRosterUi(); + } + } + } + } + }); + } + + public void checkForAvatar(Account account, final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); this.sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1972,7 +2007,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa getAvatarService().clear(account); callback.success(avatar); } else { - fetchAvatar(account, avatar, callback); + fetchAvatarPep(account, avatar, callback); } return; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java index 9f5ac988..04d55bbe 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java +++ b/src/main/java/eu/siacs/conversations/xmpp/pep/Avatar.java @@ -6,6 +6,9 @@ import eu.siacs.conversations.xmpp.jid.Jid; import android.util.Base64; public class Avatar { + + public enum Origin { PEP, VCARD }; + public String type; public String sha1sum; public String image; @@ -13,21 +16,14 @@ public class Avatar { public int width; public long size; public Jid owner; + public Origin origin = Origin.PEP; //default to maintain compat public byte[] getImageAsBytes() { return Base64.decode(image, Base64.DEFAULT); } public String getFilename() { - if (type == null) { - return sha1sum; - } else if (type.equalsIgnoreCase("image/webp")) { - return sha1sum + ".webp"; - } else if (type.equalsIgnoreCase("image/png")) { - return sha1sum + ".png"; - } else { - return sha1sum; - } + return sha1sum; } public static Avatar parseMetadata(Element items) { @@ -64,10 +60,44 @@ public class Avatar { return null; } avatar.type = child.getAttribute("type"); - avatar.sha1sum = child.getAttribute("id"); + String hash = child.getAttribute("id"); + if (!isValidSHA1(hash)) { + return null; + } + avatar.sha1sum = hash; + avatar.origin = Origin.PEP; return avatar; } } return null; } + + @Override + public boolean equals(Object object) { + if (object != null && object instanceof Avatar) { + Avatar other = (Avatar) object; + return other.getFilename().equals(this.getFilename()); + } else { + return false; + } + } + + public static Avatar parsePresence(Element x) { + Element photo = x != null ? x.findChild("photo") : null; + String hash = photo != null ? photo.getContent() : null; + if (hash == null) { + return null; + } + if (!isValidSHA1(hash)) { + return null; + } + Avatar avatar = new Avatar(); + avatar.sha1sum = hash; + avatar.origin = Origin.VCARD; + return avatar; + } + + private static boolean isValidSHA1(String s) { + return s != null && s.matches("[a-fA-F0-9]{40}"); + } } -- cgit v1.2.3 From 9eaa6800cae844b15df7b727d476fc9392f0f4bf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 08:10:16 +0200 Subject: bumped version code --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b312725e..a8b32a6b 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 61 + versionCode 62 versionName "1.4.0-alpha" } -- cgit v1.2.3 From b7c672e10e974a5eee19fb50556851e1c8d4635b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 10:29:41 +0200 Subject: avoid fetching avatars multiple times in parallel --- .../services/XmppConnectionService.java | 47 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9cee3538..6b53b758 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -41,6 +41,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -210,6 +211,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( this); private AvatarService mAvatarService = new AvatarService(this); + private final List mInProgressAvatarFetches = new ArrayList<>(); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private Integer convChangedListenerCount = 0; @@ -328,7 +330,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa message.setCounterpart(conversation.getNextCounterpart()); } if (encryption == Message.ENCRYPTION_DECRYPTED) { - getPgpEngine().encrypt(message,callback); + getPgpEngine().encrypt(message, callback); } else { callback.success(message); } @@ -1893,14 +1895,27 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchAvatar(account, avatar, null); } + private static String generateFetchKey(Account account, final Avatar avatar) { + return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum; + } + public void fetchAvatar(Account account, final Avatar avatar, final UiCallback callback) { - switch (avatar.origin) { - case PEP: - fetchAvatarPep(account,avatar,callback); - break; - case VCARD: - fetchAvatarVcard(account, avatar, callback); - break; + final String KEY = generateFetchKey(account, avatar); + synchronized(this.mInProgressAvatarFetches) { + if (this.mInProgressAvatarFetches.contains(KEY)) { + return; + } else { + switch (avatar.origin) { + case PEP: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarPep(account, avatar, callback); + break; + case VCARD: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarVcard(account, avatar, callback); + break; + } + } } } @@ -1910,6 +1925,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket result) { + synchronized (mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); + } final String ERROR = account.getJid().toBareJid() + ": fetching avatar for " + avatar.owner + " failed "; if (result.getType() == IqPacket.TYPE.RESULT) { @@ -1963,6 +1981,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.sendIqPacket(account,packet,new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { + synchronized(mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account,avatar)); + } if (packet.getType() == IqPacket.TYPE.RESULT) { Element vCard = packet.findChild("vCard","vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; @@ -2043,6 +2064,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa disconnect(account, force); } if (!account.isOptionSet(Account.OPTION_DISABLED)) { + + synchronized (this.mInProgressAvatarFetches) { + for(Iterator iterator = this.mInProgressAvatarFetches.iterator(); iterator.hasNext();) { + final String KEY = iterator.next(); + if (KEY.startsWith(account.getJid().toBareJid()+"_")) { + iterator.remove(); + } + } + } + if (account.getXmppConnection() == null) { account.setXmppConnection(createConnection(account)); } -- cgit v1.2.3 From db726a59b85146c583432bd9da58a34641356f0c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 6 May 2015 04:29:45 +0200 Subject: fwiw don't allow stanza count to go over MAX_INT --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index a2b58a14..0af6045f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -437,6 +437,10 @@ public class XmppConnection implements Runnable { throw new IOException("interrupted mid tag"); } } + if (stanzasReceived == Integer.MAX_VALUE) { + resetStreamId(); + throw new IOException("time to restart the session. cant handle >2 billion pcks"); + } ++stanzasReceived; lastPacketReceived = SystemClock.elapsedRealtime(); return element; @@ -901,6 +905,11 @@ public class XmppConnection implements Runnable { } private synchronized void sendPacket(final AbstractStanza packet) { + if (stanzasSent == Integer.MAX_VALUE) { + resetStreamId(); + disconnect(true); + return; + } final String name = packet.getName(); if (name.equals("iq") || name.equals("message") || name.equals("presence")) { ++stanzasSent; -- cgit v1.2.3 From d74e8a8a0ea20258e9e0eefbea75f94b7559f9b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 6 May 2015 04:33:21 +0200 Subject: fixed npe when missing instructions on failed register --- .../java/eu/siacs/conversations/xmpp/XmppConnection.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0af6045f..0aa67da2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -647,10 +647,8 @@ public class XmppConnection implements Runnable { if (packet.query().hasChild("username") && (packet.query().hasChild("password"))) { final IqPacket register = new IqPacket(IqPacket.TYPE.SET); - final Element username = new Element("username") - .setContent(account.getUsername()); - final Element password = new Element("password") - .setContent(account.getPassword()); + final Element username = new Element("username").setContent(account.getUsername()); + final Element password = new Element("password").setContent(account.getPassword()); register.query("jabber:iq:register").addChild(username); register.query().addChild(password); sendIqPacket(register, new OnIqPacketReceived() { @@ -663,7 +661,7 @@ public class XmppConnection implements Runnable { changeStatus(Account.State.REGISTRATION_SUCCESSFUL); } else if (packet.hasChild("error") && (packet.findChild("error") - .hasChild("conflict"))) { + .hasChild("conflict"))) { changeStatus(Account.State.REGISTRATION_CONFLICT); } else { changeStatus(Account.State.REGISTRATION_FAILED); @@ -677,7 +675,7 @@ public class XmppConnection implements Runnable { disconnect(true); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not register. instructions are" - + instructions.getContent()); + + instructions != null ? instructions.getContent() : ""); } } }); @@ -692,7 +690,7 @@ public class XmppConnection implements Runnable { } final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind") - .addChild("resource").setContent(account.getResource()); + .addChild("resource").setContent(account.getResource()); this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { -- cgit v1.2.3 From 05f0aa614f5af638c6d6da5a4c6a119e1ec6eda8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 11:07:15 +0200 Subject: fixed npe when binval value of vcard avatar is null --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 6b53b758..e58f760e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1988,8 +1988,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Element vCard = packet.findChild("vCard","vcard-temp"); Element photo = vCard != null ? vCard.findChild("PHOTO") : null; Element binval = photo != null ? photo.findChild("BINVAL") : null; - if (binval != null) { - avatar.image = binval.getContent(); + String image = binval != null ? binval.getContent() : null; + if (image != null) { + avatar.image = image; if (getFileBackend().save(avatar)) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": successfully fetched vCard avatar for " + avatar.owner); -- cgit v1.2.3 From e0653c03713efe0e4f2f5438b31d1417b059761b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 14:19:51 +0200 Subject: fixed encrypted ibb file transfer which was broken with ART. fixes #1172 --- .../xmpp/jingle/JingleConnection.java | 2 +- .../xmpp/jingle/JingleInbandTransport.java | 57 ++++++++++++---------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index e448f947..4847d5f1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -99,7 +99,7 @@ public class JingleConnection implements Downloadable { file.delete(); } } - Log.d(Config.LOGTAG,"sucessfully transmitted file:" + file.getAbsolutePath()); + Log.d(Config.LOGTAG,"successfully transmitted file:" + file.getAbsolutePath()+" ("+file.getSha1Sum()+")"); if (message.getEncryption() != Message.ENCRYPTION_PGP) { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 9866af03..4e039ad8 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -8,7 +8,9 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import android.util.Base64; +import android.util.Log; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.persistance.FileBackend; @@ -110,7 +112,11 @@ public class JingleInbandTransport extends JingleTransport { this.onFileTransmissionStatusChanged = callback; this.file = file; try { - this.remainingSize = this.file.getSize(); + if (this.file.getKey() != null) { + this.remainingSize = (this.file.getSize() / 16 + 1) * 16; + } else { + this.remainingSize = this.file.getSize(); + } this.fileSize = this.remainingSize; this.digest = MessageDigest.getInstance("SHA-1"); this.digest.reset(); @@ -150,29 +156,33 @@ public class JingleInbandTransport extends JingleTransport { byte[] buffer = new byte[this.bufferSize]; try { int count = fileInputStream.read(buffer); - if (count == -1) { + this.remainingSize -= count; + if (count != buffer.length && count != -1) { + int rem = fileInputStream.read(buffer,count,buffer.length-count); + if (rem > 0) { + count += rem; + } + } + this.digest.update(buffer,0,count); + String base64 = Base64.encodeToString(buffer,0,count, Base64.NO_WRAP); + IqPacket iq = new IqPacket(IqPacket.TYPE.SET); + iq.setTo(this.counterpart); + Element data = iq.addChild("data", "http://jabber.org/protocol/ibb"); + data.setAttribute("seq", Integer.toString(this.seq)); + data.setAttribute("block-size", Integer.toString(this.blockSize)); + data.setAttribute("sid", this.sessionId); + data.setContent(base64); + this.account.getXmppConnection().sendIqPacket(iq, this.onAckReceived); + this.seq++; + if (this.remainingSize > 0) { + connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); + } else { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - fileInputStream.close(); this.onFileTransmissionStatusChanged.onFileTransmitted(file); - } else { - this.remainingSize -= count; - this.digest.update(buffer); - String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP); - IqPacket iq = new IqPacket(IqPacket.TYPE.SET); - iq.setTo(this.counterpart); - Element data = iq.addChild("data", - "http://jabber.org/protocol/ibb"); - data.setAttribute("seq", Integer.toString(this.seq)); - data.setAttribute("block-size", - Integer.toString(this.blockSize)); - data.setAttribute("sid", this.sessionId); - data.setContent(base64); - this.account.getXmppConnection().sendIqPacket(iq, - this.onAckReceived); - this.seq++; - connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); + fileInputStream.close(); } } catch (IOException e) { + Log.d(Config.LOGTAG,e.getMessage()); FileBackend.close(fileInputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } @@ -182,14 +192,10 @@ public class JingleInbandTransport extends JingleTransport { try { byte[] buffer = Base64.decode(data, Base64.NO_WRAP); if (this.remainingSize < buffer.length) { - buffer = Arrays - .copyOfRange(buffer, 0, (int) this.remainingSize); + buffer = Arrays.copyOfRange(buffer, 0, (int) this.remainingSize); } this.remainingSize -= buffer.length; - - this.fileOutputStream.write(buffer); - this.digest.update(buffer); if (this.remainingSize <= 0) { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); @@ -200,6 +206,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { + Log.d(Config.LOGTAG,e.getMessage()); FileBackend.close(fileOutputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } -- cgit v1.2.3 From 90b74d4b800d936c270d922eaab98eaa8a1864fa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 May 2015 14:24:40 +0200 Subject: version code bumped --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a8b32a6b..0bde37f5 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 62 + versionCode 63 versionName "1.4.0-alpha" } -- cgit v1.2.3 From c4a4dd239207d95647e50f3132277e2371078d0d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2015 06:30:06 +0200 Subject: throw proper exception before changing account into error state --- .../siacs/conversations/xmpp/XmppConnection.java | 42 ++++++++++++++++------ 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0aa67da2..6c67c072 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -167,7 +167,7 @@ public class XmppConnection implements Runnable { try { String srvRecordServer; try { - srvRecordServer=IDN.toASCII(namePort.getString("name")); + srvRecordServer = IDN.toASCII(namePort.getString("name")); } catch (final IllegalArgumentException e) { // TODO: Handle me?` srvRecordServer = ""; @@ -224,6 +224,12 @@ public class XmppConnection implements Runnable { if (socket.isConnected()) { socket.close(); } + } catch (final IncompatibleServerException e) { + this.changeStatus(Account.State.INCOMPATIBLE_SERVER); + } catch (final SecurityException e) { + this.changeStatus(Account.State.SECURITY_ERROR); + } catch (final UnauthorizedException e) { + this.changeStatus(Account.State.UNAUTHORIZED); } catch (final UnknownHostException | ConnectException e) { this.changeStatus(Account.State.SERVER_NOT_FOUND); } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { @@ -231,6 +237,13 @@ public class XmppConnection implements Runnable { this.changeStatus(Account.State.OFFLINE); this.attempt--; //don't count attempt when reconnecting instantly anyway } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + + } + } if (wakeLock.isHeld()) { try { wakeLock.release(); @@ -279,8 +292,7 @@ public class XmppConnection implements Runnable { processStream(tagReader.readTag()); break; } else if (nextTag.isStart("failure")) { - tagReader.readElement(nextTag); - changeStatus(Account.State.UNAUTHORIZED); + throw new UnauthorizedException(); } else if (nextTag.isStart("challenge")) { final String challenge = tagReader.readElement(nextTag).getContent(); final Element response = new Element("response"); @@ -542,8 +554,7 @@ public class XmppConnection implements Runnable { if (!verifier.verify(account.getServer().getDomainpart(),sslSocket.getSession())) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } tagReader.setInputStream(sslSocket.getInputStream()); tagWriter.setOutputStream(sslSocket.getOutputStream()); @@ -554,8 +565,7 @@ public class XmppConnection implements Runnable { sslSocket.close(); } catch (final NoSuchAlgorithmException | KeyManagementException e1) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } } @@ -594,8 +604,7 @@ public class XmppConnection implements Runnable { " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + "). Possible downgrade attack?"); - disconnect(true); - changeStatus(Account.State.SECURITY_ERROR); + throw new SecurityException(); } } catch (final JSONException e) { Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); @@ -607,8 +616,7 @@ public class XmppConnection implements Runnable { } tagWriter.writeElement(auth); } else { - disconnect(true); - changeStatus(Account.State.INCOMPATIBLE_SERVER); + throw new IncompatibleServerException(); } } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) @@ -1098,6 +1106,18 @@ public class XmppConnection implements Runnable { public final ArrayList> identities = new ArrayList<>(); } + private class UnauthorizedException extends IOException { + + } + + private class SecurityException extends IOException { + + } + + private class IncompatibleServerException extends IOException { + + } + public class Features { XmppConnection connection; private boolean carbonsEnabled = false; -- cgit v1.2.3 From d9e5035c084a5bf307d88fb4b69c585ffb5e859b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 May 2015 06:50:28 +0200 Subject: config option to reset attempt counts when changing network (default=true) --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../services/XmppConnectionService.java | 26 +++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 5bf320a1..9f5d14fd 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -29,6 +29,7 @@ public final class Config { public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_STRING_PREP = false; // setting to true might increase startup performance public static final boolean EXTENDED_SM_LOGGING = true; // log stanza counts + public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e58f760e..34c0a5d1 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -424,6 +424,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final String action = intent == null ? null : intent.getAction(); if (action != null) { switch (action) { + case ConnectivityManager.CONNECTIVITY_ACTION: + if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) { + resetAllAttemptCounts(true); + } + break; case ACTION_MERGE_PHONE_CONTACTS: if (mRestoredFromDatabase) { PhoneHelper.loadPhoneContacts(getApplicationContext(), @@ -442,14 +447,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa toggleForegroundService(); break; case ACTION_TRY_AGAIN: - for(Account account : accounts) { - if (account.hasErrorStatus()) { - final XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.resetAttemptCount(); - } - } - } + resetAllAttemptCounts(false); break; case ACTION_DISABLE_ACCOUNT: try { @@ -531,6 +529,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return START_STICKY; } + private void resetAllAttemptCounts(boolean reallyAll) { + Log.d(Config.LOGTAG,"resetting all attepmt counts"); + for(Account account : accounts) { + if (account.hasErrorStatus() || reallyAll) { + final XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.resetAttemptCount(); + } + } + } + } + public boolean hasInternetConnection() { ConnectivityManager cm = (ConnectivityManager) getApplicationContext() .getSystemService(Context.CONNECTIVITY_SERVICE); -- cgit v1.2.3 From 9e78e3e09da47463d97a25acd051a8218fa98e54 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 8 May 2015 21:36:20 +0200 Subject: only forward incoming chat messages to Pebble App and Gadgetbridge --- .../java/eu/siacs/conversations/services/NotificationService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index fc40ce75..e111da95 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -85,7 +85,11 @@ public class NotificationService { i.putExtra("messageType", "PEBBLE_ALERT"); i.putExtra("sender", "Conversations"); /* XXX: Shouldn't be hardcoded, e.g., AbstractGenerator.APP_NAME); */ i.putExtra("notificationData", notificationData); - + // notify Pebble App + i.setPackage("com.getpebble.android"); + mXmppConnectionService.sendBroadcast(i); + // notify Gadgetbridge + i.setPackage("nodomain.freeyourgadget.gadgetbridge"); mXmppConnectionService.sendBroadcast(i); } -- cgit v1.2.3 From 4c486f5e583ddfc1f53f296d8a6fa9672981440a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 03:12:44 +0200 Subject: paint single unicode hearts as red and slightly larger --- .../eu/siacs/conversations/entities/Message.java | 72 ++++++++++++---------- .../conversations/ui/adapter/MessageAdapter.java | 26 ++++++-- .../eu/siacs/conversations/utils/UIHelper.java | 4 ++ 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 7ea3d60b..95e27c79 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -9,6 +9,7 @@ import java.util.Arrays; import eu.siacs.conversations.Config; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -95,9 +96,9 @@ public class Message extends AbstractEntity { } private Message(final String uuid, final String conversationUUid, final Jid counterpart, - final Jid trueCounterpart, final String body, final long timeSent, - final int encryption, final int status, final int type, final String remoteMsgId, - final String relativeFilePath, final String serverMsgId) { + final Jid trueCounterpart, final String body, final long timeSent, + final int encryption, final int status, final int type, final String remoteMsgId, + final String relativeFilePath, final String serverMsgId) { this.uuid = uuid; this.conversationUuid = conversationUUid; this.counterpart = counterpart; @@ -179,7 +180,7 @@ public class Message extends AbstractEntity { values.put(TYPE, type); values.put(REMOTE_MSG_ID, remoteMsgId); values.put(RELATIVE_FILE_PATH, relativeFilePath); - values.put(SERVER_MSG_ID,serverMsgId); + values.put(SERVER_MSG_ID, serverMsgId); return values; } @@ -211,7 +212,7 @@ public class Message extends AbstractEntity { return null; } else { return this.conversation.getAccount().getRoster() - .getContactFromRoster(this.trueCounterpart); + .getContactFromRoster(this.trueCounterpart); } } } @@ -359,34 +360,36 @@ public class Message extends AbstractEntity { public boolean mergeable(final Message message) { return message != null && - (message.getType() == Message.TYPE_TEXT && - this.getDownloadable() == null && - message.getDownloadable() == null && - message.getEncryption() != Message.ENCRYPTION_PGP && - this.getType() == message.getType() && - //this.getStatus() == message.getStatus() && - isStatusMergeable(this.getStatus(),message.getStatus()) && - this.getEncryption() == message.getEncryption() && - this.getCounterpart() != null && - this.getCounterpart().equals(message.getCounterpart()) && - (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && - !GeoHelper.isGeoUri(message.getBody()) && - !GeoHelper.isGeoUri(this.body) && - !message.bodyContainsDownloadable() && - !this.bodyContainsDownloadable() && - !message.getBody().startsWith(ME_COMMAND) && - !this.getBody().startsWith(ME_COMMAND) - ); + (message.getType() == Message.TYPE_TEXT && + this.getDownloadable() == null && + message.getDownloadable() == null && + message.getEncryption() != Message.ENCRYPTION_PGP && + this.getType() == message.getType() && + //this.getStatus() == message.getStatus() && + isStatusMergeable(this.getStatus(), message.getStatus()) && + this.getEncryption() == message.getEncryption() && + this.getCounterpart() != null && + this.getCounterpart().equals(message.getCounterpart()) && + (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && + !GeoHelper.isGeoUri(message.getBody()) && + !GeoHelper.isGeoUri(this.body) && + !message.bodyContainsDownloadable() && + !this.bodyContainsDownloadable() && + !message.getBody().startsWith(ME_COMMAND) && + !this.getBody().startsWith(ME_COMMAND) && + !this.bodyIsHeart() && + !message.bodyIsHeart() + ); } private static boolean isStatusMergeable(int a, int b) { return a == b || ( - ( a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND_RECEIVED) - || (a == Message.STATUS_SEND && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND && b == Message.STATUS_SEND_RECEIVED) + (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_UNSEND) + || (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_SEND) + || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND) + || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND_RECEIVED) + || (a == Message.STATUS_SEND && b == Message.STATUS_UNSEND) + || (a == Message.STATUS_SEND && b == Message.STATUS_SEND_RECEIVED) ); } @@ -443,7 +446,7 @@ public class Message extends AbstractEntity { if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { return false; - } + } String sUrlPath = url.getPath(); if (sUrlPath == null || sUrlPath.isEmpty()) { @@ -457,14 +460,14 @@ public class Message extends AbstractEntity { String[] extensionParts = sLastUrlPath.split("\\."); if (extensionParts.length == 2 && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 1])) { + extensionParts[extensionParts.length - 1])) { return true; } else if (extensionParts.length == 3 && Arrays .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) .contains(extensionParts[extensionParts.length - 1]) && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 2])) { + extensionParts[extensionParts.length - 2])) { return true; } else { return false; @@ -474,6 +477,11 @@ public class Message extends AbstractEntity { } } + public boolean bodyIsHeart() { + return body != null && + (body.trim().equals(UIHelper.BLACK_HEART_SUIT) || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT)); + } + public ImageParams getImageParams() { ImageParams params = getLegacyImageParams(); if (params != null) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index da92fb18..89618dfc 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -7,7 +7,9 @@ import android.graphics.Typeface; import android.net.Uri; import android.text.Spannable; import android.text.SpannableString; +import android.text.Spanned; import android.text.style.ForegroundColorSpan; +import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; import android.util.Log; @@ -207,12 +209,24 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); + R.string.decryption_failed)); viewHolder.messageBody.setTextColor(activity.getWarningTextColor()); viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); viewHolder.messageBody.setTextIsSelectable(false); } + private void displayHeartMesage(final ViewHolder viewHolder, final String body) { + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + Spannable span = new SpannableString(body); + span.setSpan(new RelativeSizeSpan(4.0f),0,body.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()),0,body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); + } + private void displayTextMessage(final ViewHolder viewHolder, final Message message) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); @@ -289,7 +303,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity,message))); + viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message))); viewHolder.download_button.setOnClickListener(new OnClickListener() { @Override @@ -334,7 +348,7 @@ public class MessageAdapter extends ArrayAdapter { scalledH = (int) (params.height / ((double) params.width / target)); } viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams( - scalledW, scalledH)); + scalledW, scalledH)); activity.loadBitmap(message, viewHolder.image); viewHolder.image.setOnClickListener(new OnClickListener() { @@ -528,7 +542,11 @@ public class MessageAdapter extends ArrayAdapter { if (GeoHelper.isGeoUri(message.getBody())) { displayLocationMessage(viewHolder,message); } else { - displayTextMessage(viewHolder, message); + if (message.bodyIsHeart()) { + displayHeartMesage(viewHolder," "+message.getBody().trim()+" "); + } else { + displayTextMessage(viewHolder, message); + } } } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index c3195d86..49354753 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -17,6 +17,10 @@ import android.text.format.DateUtils; import android.util.Pair; public class UIHelper { + + public static String BLACK_HEART_SUIT = "\u2665"; + public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME -- cgit v1.2.3 From 1e28f600386f1f1dcd734363c932d5ccbd6267fb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 03:14:13 +0200 Subject: changed conversation red to material red --- art/ic_send_cancel_dnd.svg | 2 +- art/ic_send_location_dnd.svg | 2 +- art/ic_send_photo_dnd.svg | 4 ++-- art/ic_send_text_dnd.svg | 2 +- art/ic_send_voice_dnd.svg | 2 +- .../java/eu/siacs/conversations/entities/Contact.java | 4 ++-- src/main/res/drawable-hdpi/ic_send_cancel_dnd.png | Bin 1559 -> 1587 bytes src/main/res/drawable-hdpi/ic_send_location_dnd.png | Bin 1333 -> 1333 bytes src/main/res/drawable-hdpi/ic_send_photo_dnd.png | Bin 1381 -> 1383 bytes src/main/res/drawable-hdpi/ic_send_text_dnd.png | Bin 1126 -> 1128 bytes src/main/res/drawable-hdpi/ic_send_voice_dnd.png | Bin 1149 -> 1161 bytes src/main/res/drawable-mdpi/ic_send_cancel_dnd.png | Bin 1040 -> 1025 bytes src/main/res/drawable-mdpi/ic_send_location_dnd.png | Bin 908 -> 917 bytes src/main/res/drawable-mdpi/ic_send_photo_dnd.png | Bin 909 -> 915 bytes src/main/res/drawable-mdpi/ic_send_text_dnd.png | Bin 769 -> 781 bytes src/main/res/drawable-mdpi/ic_send_voice_dnd.png | Bin 774 -> 795 bytes src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png | Bin 1940 -> 1958 bytes src/main/res/drawable-xhdpi/ic_send_location_dnd.png | Bin 1721 -> 1753 bytes src/main/res/drawable-xhdpi/ic_send_photo_dnd.png | Bin 1723 -> 1756 bytes src/main/res/drawable-xhdpi/ic_send_text_dnd.png | Bin 1395 -> 1430 bytes src/main/res/drawable-xhdpi/ic_send_voice_dnd.png | Bin 1426 -> 1419 bytes src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png | Bin 2911 -> 2983 bytes src/main/res/drawable-xxhdpi/ic_send_location_dnd.png | Bin 2578 -> 2589 bytes src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png | Bin 2588 -> 2618 bytes src/main/res/drawable-xxhdpi/ic_send_text_dnd.png | Bin 2004 -> 2005 bytes src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png | Bin 2152 -> 2200 bytes src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png | Bin 3791 -> 3862 bytes .../res/drawable-xxxhdpi/ic_send_location_dnd.png | Bin 3456 -> 3514 bytes src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png | Bin 3544 -> 3569 bytes src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png | Bin 2597 -> 2592 bytes src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png | Bin 2811 -> 2849 bytes src/main/res/values/colors.xml | 2 +- 32 files changed, 9 insertions(+), 9 deletions(-) diff --git a/art/ic_send_cancel_dnd.svg b/art/ic_send_cancel_dnd.svg index 54e02a91..67a562b2 100644 --- a/art/ic_send_cancel_dnd.svg +++ b/art/ic_send_cancel_dnd.svg @@ -50,5 +50,5 @@ + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_location_dnd.svg b/art/ic_send_location_dnd.svg index d91fa913..705cdb6f 100644 --- a/art/ic_send_location_dnd.svg +++ b/art/ic_send_location_dnd.svg @@ -50,5 +50,5 @@ + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_photo_dnd.svg b/art/ic_send_photo_dnd.svg index 0e406ede..9ef8b782 100644 --- a/art/ic_send_photo_dnd.svg +++ b/art/ic_send_photo_dnd.svg @@ -52,9 +52,9 @@ cy="24" r="6.4" id="circle4" - style="fill:#e51c23;fill-opacity:0.627451" /> + style="fill:#f44336;fill-opacity:0.627451" /> + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/art/ic_send_text_dnd.svg b/art/ic_send_text_dnd.svg index b594f319..1b7ad51f 100644 --- a/art/ic_send_text_dnd.svg +++ b/art/ic_send_text_dnd.svg @@ -58,7 +58,7 @@ id="grid3631" /> + style="fill:#f44336;fill-opacity:0.627451" /> diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index 4ad105b1..9dbca59a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -140,10 +140,10 @@ public class Contact implements ListItem, Blockable { tags.add(new Tag("away", 0xffff9800)); break; case Presences.XA: - tags.add(new Tag("not available", 0xffe51c23)); + tags.add(new Tag("not available", 0xfff44336)); break; case Presences.DND: - tags.add(new Tag("dnd", 0xffe51c23)); + tags.add(new Tag("dnd", 0xfff44336)); break; } if (isBlocked()) { diff --git a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png index cbfd8e76..83a7b94b 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-hdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_location_dnd.png b/src/main/res/drawable-hdpi/ic_send_location_dnd.png index 3bcbe18a..a9c51317 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_location_dnd.png and b/src/main/res/drawable-hdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png index 2eb85679..15b1eb7a 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-hdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_text_dnd.png b/src/main/res/drawable-hdpi/ic_send_text_dnd.png index 706b6505..b43428de 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_text_dnd.png and b/src/main/res/drawable-hdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png index 50184ee8..26a89e8e 100644 Binary files a/src/main/res/drawable-hdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-hdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png index e4fa38a3..75006446 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-mdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_location_dnd.png b/src/main/res/drawable-mdpi/ic_send_location_dnd.png index 92e68ee3..3f4d6aa4 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_location_dnd.png and b/src/main/res/drawable-mdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png index 7b6700d6..08033f63 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-mdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_text_dnd.png b/src/main/res/drawable-mdpi/ic_send_text_dnd.png index 92df9d3d..c3d9e79a 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_text_dnd.png and b/src/main/res/drawable-mdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png index ef25b1c4..aaf8ff32 100644 Binary files a/src/main/res/drawable-mdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-mdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png index 276ad024..dde1b707 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png index 90ce346c..99c8ce36 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png index 2c37db74..fc69cb41 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png index 0a749f8d..8b93ec10 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png index cea4212a..66b0c677 100644 Binary files a/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png index 93fbc44d..e68a912d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png index ea3d1502..1773e62d 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png index 09c11a81..fe33a1d0 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png index 0d7e7053..32f5e29c 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png index a5151331..4a5b4104 100644 Binary files a/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png index 02ab1d0f..307ca8a0 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_cancel_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png index 08e2b39b..e7f6fde7 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_location_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png index fccb32dc..8a9b0700 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_photo_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png index 929a33a4..b11cd6b6 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_text_dnd.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png index 8ac667be..4ad9d389 100644 Binary files a/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png and b/src/main/res/drawable-xxxhdpi/ic_send_voice_dnd.png differ diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index c21650a5..753a56df 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -11,7 +11,7 @@ #ffeeeeee #ff323232 #1f000000 - #ffe51c23 + #fff44336 #ffff9800 #ff259b24 -- cgit v1.2.3 From 33d1621e3b2c9a34689dfddc71eeb9ee4d91c348 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 11:56:23 +0200 Subject: added white heart to new rendering as well --- src/main/java/eu/siacs/conversations/entities/Message.java | 4 +++- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 95e27c79..4dac0b98 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -479,7 +479,9 @@ public class Message extends AbstractEntity { public boolean bodyIsHeart() { return body != null && - (body.trim().equals(UIHelper.BLACK_HEART_SUIT) || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT)); + (body.trim().equals(UIHelper.BLACK_HEART_SUIT) + || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT) + || body.trim().equals(UIHelper.WHITE_HEART_SUIT)); } public ImageParams getImageParams() { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 49354753..2cfd5823 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -20,6 +20,7 @@ public class UIHelper { public static String BLACK_HEART_SUIT = "\u2665"; public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + public static String WHITE_HEART_SUIT = "\u2661"; private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 239e86a98a4af8ab7ce7f6b96bed0bb4dc9e4bb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 12:04:11 +0200 Subject: optimized heart render code a bit --- src/main/java/eu/siacs/conversations/entities/Message.java | 5 +---- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 10 +++++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 4dac0b98..c87e5518 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -478,10 +478,7 @@ public class Message extends AbstractEntity { } public boolean bodyIsHeart() { - return body != null && - (body.trim().equals(UIHelper.BLACK_HEART_SUIT) - || body.trim().equals(UIHelper.HEAVY_BLACK_HEART_SUIT) - || body.trim().equals(UIHelper.WHITE_HEART_SUIT)); + return body != null && UIHelper.HEARTS.contains(body.trim()); } public ImageParams getImageParams() { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2cfd5823..9c62dcbf 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.utils; import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -18,9 +20,11 @@ import android.util.Pair; public class UIHelper { - public static String BLACK_HEART_SUIT = "\u2665"; - public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; - public static String WHITE_HEART_SUIT = "\u2661"; + private static String BLACK_HEART_SUIT = "\u2665"; + private static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static String WHITE_HEART_SUIT = "\u2661"; + + public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 22b12091a103a164a1d54874ad376d02dfee1519 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 07:57:52 +0200 Subject: rewrote parts of message adapter to avoid using NULL views --- .../siacs/conversations/entities/Conversation.java | 6 +++ .../conversations/ui/ConversationFragment.java | 48 +++++++++++++--------- .../conversations/ui/adapter/MessageAdapter.java | 41 +++--------------- src/main/res/layout/message_null.xml | 7 ---- 4 files changed, 41 insertions(+), 61 deletions(-) delete mode 100644 src/main/res/layout/message_null.xml diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index bfee5007..95a8c957 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -16,6 +16,7 @@ import java.security.interfaces.DSAPublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import eu.siacs.conversations.Config; @@ -218,6 +219,11 @@ public class Conversation extends AbstractEntity implements Blockable { messages.clear(); messages.addAll(this.messages); } + for(Iterator iterator = messages.iterator(); iterator.hasNext();) { + if (iterator.next().wasMergedIntoPrevious()) { + iterator.remove(); + } + } } @Override diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 6b11d310..b6a7dc76 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -117,6 +117,27 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } + private int getIndexOf(String uuid, List messages) { + if (uuid == null) { + return 0; + } + for(int i = 0; i < messages.size(); ++i) { + if (uuid.equals(messages.get(i).getUuid())) { + return i; + } else { + Message next = messages.get(i); + while(next != null && next.wasMergedIntoPrevious()) { + if (uuid.equals(next.getUuid())) { + return i; + } + next = next.next(); + } + + } + } + return 0; + } + @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { @@ -126,7 +147,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa messagesLoaded = false; activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() { @Override - public void onMoreMessagesLoaded(final int count, Conversation conversation) { + public void onMoreMessagesLoaded(final int c, Conversation conversation) { if (ConversationFragment.this.conversation != conversation) { return; } @@ -134,29 +155,18 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void run() { final int oldPosition = messagesView.getFirstVisiblePosition(); + Message message = messageList.get(oldPosition); + String uuid = message != null ? message.getUuid() : null; View v = messagesView.getChildAt(0); final int pxOffset = (v == null) ? 0 : v.getTop(); ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList); updateStatusMessages(); messageListAdapter.notifyDataSetChanged(); - if (count != 0) { - final int newPosition = oldPosition + count; - int offset = 0; - try { - Message tmpMessage = messageList.get(newPosition); - - while (tmpMessage.wasMergedIntoPrevious()) { - offset++; - tmpMessage = tmpMessage.prev(); - } - } catch (final IndexOutOfBoundsException ignored) { - - } - messagesView.setSelectionFromTop(newPosition - offset, pxOffset); - messagesLoaded = true; - if (messageLoaderToast != null) { - messageLoaderToast.cancel(); - } + int pos = getIndexOf(uuid,messageList); + messagesView.setSelectionFromTop(pos, pxOffset); + messagesLoaded = true; + if (messageLoaderToast != null) { + messageLoaderToast.cancel(); } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 89618dfc..b23709fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -12,7 +12,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; @@ -26,7 +25,6 @@ import android.widget.Toast; import java.util.List; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; @@ -44,7 +42,6 @@ public class MessageAdapter extends ArrayAdapter { private static final int SENT = 0; private static final int RECEIVED = 1; private static final int STATUS = 2; - private static final int NULL = 3; private ConversationActivity activity; @@ -79,14 +76,12 @@ public class MessageAdapter extends ArrayAdapter { @Override public int getViewTypeCount() { - return 4; + return 3; } @Override public int getItemViewType(int position) { - if (getItem(position).wasMergedIntoPrevious()) { - return NULL; - } else if (getItem(position).getType() == Message.TYPE_STATUS) { + if (getItem(position).getType() == Message.TYPE_STATUS) { return STATUS; } else if (getItem(position).getStatus() <= Message.STATUS_RECEIVED) { return RECEIVED; @@ -222,8 +217,8 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); Spannable span = new SpannableString(body); - span.setSpan(new RelativeSizeSpan(4.0f),0,body.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()),0,body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); viewHolder.messageBody.setText(span); } @@ -235,8 +230,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); - final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND, - nick + " "); + final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { final Spannable span = new SpannableString(formattedBody); @@ -244,7 +238,7 @@ public class MessageAdapter extends ArrayAdapter { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); viewHolder.messageBody.setText(span); } else { - viewHolder.messageBody.setText(message.getMergedBody()); + viewHolder.messageBody.setText(formattedBody); } } else { String privateMarker; @@ -373,10 +367,6 @@ public class MessageAdapter extends ArrayAdapter { if (view == null) { viewHolder = new ViewHolder(); switch (type) { - case NULL: - view = activity.getLayoutInflater().inflate( - R.layout.message_null, parent, false); - break; case SENT: view = activity.getLayoutInflater().inflate( R.layout.message_sent, parent, false); @@ -443,25 +433,6 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.status_message.setText(message.getBody()); } return view; - } else if (type == NULL) { - if (viewHolder.message_box != null) { - Log.e(Config.LOGTAG, "detected type=NULL but with wrong cached view"); - view = activity.getLayoutInflater().inflate(R.layout.message_null, parent, false); - view.setTag(new ViewHolder()); - } - if (position == getCount() - 1) { - view.getLayoutParams().height = 1; - } else { - view.getLayoutParams().height = 0; - - } - view.setLayoutParams(view.getLayoutParams()); - return view; - } else if (message.wasMergedIntoPrevious()) { - Log.e(Config.LOGTAG,"detected wasMergedIntoPrevious with wrong type"); - return view; - } else if (viewHolder.messageBody == null || viewHolder.image == null) { - return view; //avoiding weird platform bugs } else if (type == RECEIVED) { Contact contact = message.getContact(); if (contact != null) { diff --git a/src/main/res/layout/message_null.xml b/src/main/res/layout/message_null.xml deleted file mode 100644 index 0e0f1c92..00000000 --- a/src/main/res/layout/message_null.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file -- cgit v1.2.3 From 21deda7b0029b729c94af9f1551278859b78f119 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 08:45:38 +0200 Subject: no font padding on red hearts --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index b23709fc..060bef71 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -210,12 +210,13 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setTextIsSelectable(false); } - private void displayHeartMesage(final ViewHolder viewHolder, final String body) { + private void displayHeartMessage(final ViewHolder viewHolder, final String body) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(false); Spannable span = new SpannableString(body); span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -228,6 +229,7 @@ public class MessageAdapter extends ArrayAdapter { } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(true); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); @@ -514,7 +516,7 @@ public class MessageAdapter extends ArrayAdapter { displayLocationMessage(viewHolder,message); } else { if (message.bodyIsHeart()) { - displayHeartMesage(viewHolder," "+message.getBody().trim()+" "); + displayHeartMessage(viewHolder, message.getBody().trim()); } else { displayTextMessage(viewHolder, message); } -- cgit v1.2.3 From 53e43daa0d8143d9a5abcd1391153b88a4702914 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 09:08:56 +0200 Subject: add a little bit of space between merged messages. --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- .../java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index c87e5518..3c144f5c 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -396,7 +396,7 @@ public class Message extends AbstractEntity { public String getMergedBody() { final Message next = this.next(); if (this.mergeable(next)) { - return getBody().trim() + '\n' + next.getMergedBody(); + return getBody().trim() + "\n\n" + next.getMergedBody(); } return getBody().trim(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 060bef71..0730f0e1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -232,7 +232,13 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setIncludeFontPadding(true); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); - final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); + final String body = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); + final SpannableString formattedBody = new SpannableString(body); + int i = body.indexOf("\n\n"); + while(i >= 0) { + formattedBody.setSpan(new RelativeSizeSpan(0.2f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + i = body.indexOf("\n\n",i+2); + } if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { final Spannable span = new SpannableString(formattedBody); -- cgit v1.2.3 From 9156665addb5541cacf640f033f03cec0937f052 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 09:20:08 +0200 Subject: increased space between merged messages a bit --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 0730f0e1..ec351622 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -236,7 +236,7 @@ public class MessageAdapter extends ArrayAdapter { final SpannableString formattedBody = new SpannableString(body); int i = body.indexOf("\n\n"); while(i >= 0) { - formattedBody.setSpan(new RelativeSizeSpan(0.2f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); i = body.indexOf("\n\n",i+2); } if (message.getType() != Message.TYPE_PRIVATE) { -- cgit v1.2.3 From b6f85ba0dd765e72a89a85461b3f8c48f038270c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 14:18:30 +0200 Subject: avoid using paragraph style breaks by accident --- src/main/java/eu/siacs/conversations/entities/Message.java | 4 +++- .../java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 3c144f5c..217b82bb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -17,6 +17,8 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; + public static final String MERGE_SEPARATOR = "\u2029\n\n"; + public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; public static final int STATUS_SEND = 2; @@ -396,7 +398,7 @@ public class Message extends AbstractEntity { public String getMergedBody() { final Message next = this.next(); if (this.mergeable(next)) { - return getBody().trim() + "\n\n" + next.getMergedBody(); + return getBody().trim() + MERGE_SEPARATOR + next.getMergedBody(); } return getBody().trim(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index ec351622..29dfced2 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -234,10 +234,11 @@ public class MessageAdapter extends ArrayAdapter { final String nick = UIHelper.getMessageDisplayName(message); final String body = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND,nick + " "); final SpannableString formattedBody = new SpannableString(body); - int i = body.indexOf("\n\n"); + int i = body.indexOf(Message.MERGE_SEPARATOR); while(i >= 0) { - formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,i+2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - i = body.indexOf("\n\n",i+2); + final int end = i + Message.MERGE_SEPARATOR.length(); + formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + i = body.indexOf(Message.MERGE_SEPARATOR,end); } if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { -- cgit v1.2.3 From ceadf2f6fb67666abb0d8f9b84a91841396cfc0a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 May 2015 14:28:36 +0200 Subject: pulled updated translations from transifex --- src/main/res/values-ru/strings.xml | 2 ++ src/main/res/values-sr/strings.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 2fc257f7..7b104820 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -441,11 +441,13 @@ Удалён %d сертификат Удалено %d сертификатов + Удалено %d сертификатов Выбран %d контакт Выбрано %d контактов + Выбрано %d контактов diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index bcf420ba..ea5cbdb8 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -97,8 +97,8 @@ Опште ИксМПП ресурс Име са којим се овај клијент идентификује - Прихваћај фајлове - Аутоматски прихваћај фајлове мање од… + Прихватај фајлове + Аутоматски прихватај фајлове мање од… Поставке обавештења Обавештења Обавести кад стигне нова порука -- cgit v1.2.3 From fe5c4cab4608a6b3ded682f4a69da14916cc1d37 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 03:56:13 +0200 Subject: don't reinit conversation when coming back to activity. avoids unnecessary scrolling --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index b11ff002..6e175d8e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -927,9 +927,7 @@ public class ConversationActivity extends XmppActivity } this.mConversationFragment.reInit(getSelectedConversation()); mOpenConverstaion = null; - } else if (getSelectedConversation() != null) { - this.mConversationFragment.reInit(getSelectedConversation()); - } else { + } else if (getSelectedConversation() == null) { showConversationsOverview(); mPendingImageUris.clear(); mPendingFileUris.clear(); -- cgit v1.2.3 From 93e444ac3ad4b39415d7097566c319904ff14bcd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 03:57:05 +0200 Subject: don't set unknown error in muc --- src/main/java/eu/siacs/conversations/entities/MucOptions.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index addee8db..d867a370 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -343,8 +343,6 @@ public class MucOptions { setError(ERROR_BANNED); } else if (error != null && error.hasChild("registration-required")) { setError(ERROR_MEMBERS_ONLY); - } else { - setError(ERROR_UNKNOWN); } } } -- cgit v1.2.3 From d3a6aa9f7a3132f8f67f2de99b4afbaba7823abb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 04:33:04 +0200 Subject: handle conference invites differently to deal with killed activities. fixes #1188 --- .../services/XmppConnectionService.java | 1 + .../ui/ConferenceDetailsActivity.java | 4 + .../conversations/ui/ConversationActivity.java | 6 ++ .../eu/siacs/conversations/ui/XmppActivity.java | 87 ++++++++++++++-------- 4 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 34c0a5d1..0ed89206 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2108,6 +2108,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void invite(Conversation conversation, Jid contact) { + Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+": inviting "+contact+" to "+conversation.getJid().toBareJid()); MessagePacket packet = mMessageGenerator.invite(conversation, contact); sendMessagePacket(conversation.getAccount(), packet); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 8c4f6eaf..07b8819d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -385,6 +385,10 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override void onBackendConnected() { + if (mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } if (getIntent().getAction().equals(ACTION_VIEW_MUC)) { this.uuid = getIntent().getExtras().getString("uuid"); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 6e175d8e..a2a405c3 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -901,6 +901,12 @@ public class ConversationActivity extends XmppActivity void onBackendConnected() { this.xmppConnectionService.getNotificationService().setIsInForeground(true); updateConversationList(); + + if (mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } + if (xmppConnectionService.getAccounts().size() == 0) { if (!mRedirected) { this.mRedirected = true; diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 392e57a7..71fb62b5 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -113,6 +113,8 @@ public abstract class XmppActivity extends Activity { } }; + protected ConferenceInvite mPendingConferenceInvite = null; + protected void refreshUi() { final long diff = SystemClock.elapsedRealtime() - mLastUiRefresh; @@ -367,7 +369,7 @@ public abstract class XmppActivity extends Activity { } public void highlightInMuc(Conversation conversation, String nick) { - switchToConversation(conversation,null,nick,false); + switchToConversation(conversation, null, nick, false); } private void switchToConversation(Conversation conversation, String text, String nick, boolean newTask) { @@ -435,7 +437,7 @@ public abstract class XmppActivity extends Activity { @Override public void userInputRequried(PendingIntent pi, - Account account) { + Account account) { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); @@ -446,13 +448,13 @@ public abstract class XmppActivity extends Activity { @Override public void success(Account account) { xmppConnectionService.databaseBackend - .updateAccount(account); + .updateAccount(account); xmppConnectionService.sendPresence(account); if (conversation != null) { conversation - .setNextEncryption(Message.ENCRYPTION_PGP); + .setNextEncryption(Message.ENCRYPTION_PGP); xmppConnectionService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); } } @@ -665,32 +667,13 @@ public abstract class XmppActivity extends Activity { protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_INVITE_TO_CONVERSATION - && resultCode == RESULT_OK) { - try { - String conversationUuid = data.getStringExtra("conversation"); - Conversation conversation = xmppConnectionService - .findConversationByUuid(conversationUuid); - List jids = new ArrayList(); - if (data.getBooleanExtra("multiple", false)) { - String[] toAdd = data.getStringArrayExtra("contacts"); - for (String item : toAdd) { - jids.add(Jid.fromString(item)); - } - } else { - jids.add(Jid.fromString(data.getStringExtra("contact"))); - } - - if (conversation.getMode() == Conversation.MODE_MULTI) { - for (Jid jid : jids) { - xmppConnectionService.invite(conversation, jid); - } - } else { - jids.add(conversation.getJid().toBareJid()); - xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback); - } - } catch (final InvalidJidException ignored) { - + if (requestCode == REQUEST_INVITE_TO_CONVERSATION && resultCode == RESULT_OK) { + mPendingConferenceInvite = ConferenceInvite.parse(data); + if (xmppConnectionServiceBound && mPendingConferenceInvite != null) { + mPendingConferenceInvite.execute(this); + mPendingConferenceInvite = null; + } else { + Log.d(Config.LOGTAG,"putting invite on pending"); } } } @@ -855,6 +838,48 @@ public abstract class XmppActivity extends Activity { } } + public static class ConferenceInvite { + private String uuid; + private List jids = new ArrayList<>(); + + public static ConferenceInvite parse(Intent data) { + ConferenceInvite invite = new ConferenceInvite(); + invite.uuid = data.getStringExtra("conversation"); + if (invite.uuid == null) { + return null; + } + try { + if (data.getBooleanExtra("multiple", false)) { + String[] toAdd = data.getStringArrayExtra("contacts"); + for (String item : toAdd) { + invite.jids.add(Jid.fromString(item)); + } + } else { + invite.jids.add(Jid.fromString(data.getStringExtra("contact"))); + } + } catch (final InvalidJidException ignored) { + return null; + } + return invite; + } + + public void execute(XmppActivity activity) { + XmppConnectionService service = activity.xmppConnectionService; + Conversation conversation = service.findConversationByUuid(this.uuid); + if (conversation == null) { + return; + } + if (conversation.getMode() == Conversation.MODE_MULTI) { + for (Jid jid : jids) { + service.invite(conversation, jid); + } + } else { + jids.add(conversation.getJid().toBareJid()); + service.createAdhocConference(conversation.getAccount(), jids, activity.adhocCallback); + } + } + } + public AvatarService avatarService() { return xmppConnectionService.getAvatarService(); } -- cgit v1.2.3 From 93e620d6858cd713c8895256f3233e9d0bd75d74 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 May 2015 04:40:57 +0200 Subject: removed debug logging --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 71fb62b5..934c696f 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -672,8 +672,6 @@ public abstract class XmppActivity extends Activity { if (xmppConnectionServiceBound && mPendingConferenceInvite != null) { mPendingConferenceInvite.execute(this); mPendingConferenceInvite = null; - } else { - Log.d(Config.LOGTAG,"putting invite on pending"); } } } -- cgit v1.2.3 From f84ccbe1fa3efe3463f0e18ed98c7124a8b4806b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 11:56:25 +0200 Subject: version bump to 1.4.0-alpha3 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0bde37f5..c47e6ee1 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 63 - versionName "1.4.0-alpha" + versionCode 64 + versionName "1.4.0-alpha3" } compileOptions { -- cgit v1.2.3 From 51aeeb766c5c0ad649abad7777bb5e194a6ae997 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 11:56:59 +0200 Subject: use zero width white space as message seperator --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 217b82bb..a8bb9c55 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -17,7 +17,7 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; - public static final String MERGE_SEPARATOR = "\u2029\n\n"; + public static final String MERGE_SEPARATOR = "\u200B\n\n"; public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; -- cgit v1.2.3 From 6489ddac6c6d3d6eced35ab4640963eb15667bb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 14:33:52 +0200 Subject: clear avatar cache when uploading new avatar --- src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0ed89206..4f2697a3 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1879,6 +1879,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa IqPacket result) { if (result.getType() == IqPacket.TYPE.RESULT) { if (account.setAvatar(avatar.getFilename())) { + getAvatarService().clear(account); databaseBackend.updateAccount(account); } callback.success(avatar); -- cgit v1.2.3 From 82878cded1007331e953908dee11c66557e9ae20 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 16:23:20 +0200 Subject: show location quick action after receiving a question about the users location --- .../conversations/ui/ConversationFragment.java | 5 ++++- .../eu/siacs/conversations/utils/UIHelper.java | 24 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index b6a7dc76..20fc1750 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -59,6 +59,7 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jid.Jid; @@ -905,7 +906,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } else { if (empty) { String setting = activity.getPreferences().getString("quick_action","recent"); - if (setting.equals("recent")) { + if (!setting.equals("none") && UIHelper.receivedLocationQuestion(conversation.getLatestMessage())) { + setting = "location"; + } else if (setting.equals("recent")) { setting = activity.getPreferences().getString("recently_used_quick_action","text"); } switch (setting) { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 9c62dcbf..e289e0e5 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; @@ -26,6 +27,19 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); + private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( + "where are you?", //en + "where r u?", //en + "whats your 20?", //en + "what is your 20?", //en + "what's your 20?", //en + "whats your twenty?", //en + "what is your twenty?", //en + "what's your twenty?", //en + "wo bist du?", //de + "wo sind sie?" //de + )); + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME @@ -234,4 +248,14 @@ public class UIHelper { return counterpart.toString().trim(); } } + + public static boolean receivedLocationQuestion(Message message) { + if (message == null + || message.getStatus() != Message.STATUS_RECEIVED + || message.getType() != Message.TYPE_TEXT) { + return false; + } + String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + return LOCATION_QUESTIONS.contains(body); + } } -- cgit v1.2.3 From 4414cf3b277ec7a0a015e23eab197374f3714da6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 17:10:11 +0200 Subject: ignore question marks in location question --- .../eu/siacs/conversations/utils/UIHelper.java | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index e289e0e5..51984c91 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -28,16 +28,18 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( - "where are you?", //en - "where r u?", //en - "whats your 20?", //en - "what is your 20?", //en - "what's your 20?", //en - "whats your twenty?", //en - "what is your twenty?", //en - "what's your twenty?", //en - "wo bist du?", //de - "wo sind sie?" //de + "where are you", //en + "where r u", //en + "whats your 20", //en + "what is your 20", //en + "what's your 20", //en + "whats your twenty", //en + "what is your twenty", //en + "what's your twenty", //en + "wo bist du", //de + "wo sind sie", //de + "wo seid ihr", //de + "dónde estás" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE @@ -256,6 +258,7 @@ public class UIHelper { return false; } String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } } -- cgit v1.2.3 From 8d472157a4b706ef0c5fc422325f0c1ad47e96bd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 11:57:51 +0200 Subject: always log reason for failed file transfer --- .../conversations/xmpp/jingle/JingleInbandTransport.java | 8 ++++++-- .../conversations/xmpp/jingle/JingleSocks5Transport.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index 4e039ad8..29efcf8f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -97,11 +97,13 @@ public class JingleInbandTransport extends JingleTransport { file.createNewFile(); this.fileOutputStream = file.createOutputStream(); if (this.fileOutputStream == null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not create output stream"); callback.onFileTransferAborted(); return; } this.remainingSize = this.fileSize = file.getExpectedSize(); } catch (final NoSuchAlgorithmException | IOException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+" "+e.getMessage()); callback.onFileTransferAborted(); } } @@ -122,6 +124,7 @@ public class JingleInbandTransport extends JingleTransport { this.digest.reset(); fileInputStream = this.file.createInputStream(); if (fileInputStream == null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could no create input stream"); callback.onFileTransferAborted(); return; } @@ -130,6 +133,7 @@ public class JingleInbandTransport extends JingleTransport { } } catch (NoSuchAlgorithmException e) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); } } @@ -182,7 +186,7 @@ public class JingleInbandTransport extends JingleTransport { fileInputStream.close(); } } catch (IOException e) { - Log.d(Config.LOGTAG,e.getMessage()); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); FileBackend.close(fileInputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } @@ -206,7 +210,7 @@ public class JingleInbandTransport extends JingleTransport { connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100)); } } catch (IOException e) { - Log.d(Config.LOGTAG,e.getMessage()); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage()); FileBackend.close(fileOutputStream); this.onFileTransmissionStatusChanged.onFileTransferAborted(); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 72015a05..35375a5d 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.xmpp.jingle; +import android.util.Log; + import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -10,6 +12,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.CryptoHelper; @@ -102,6 +105,7 @@ public class JingleSocks5Transport extends JingleTransport { digest.reset(); fileInputStream = file.createInputStream(); if (fileInputStream == null) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create input stream"); callback.onFileTransferAborted(); return; } @@ -121,10 +125,13 @@ public class JingleSocks5Transport extends JingleTransport { callback.onFileTransmitted(file); } } catch (FileNotFoundException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (IOException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } finally { FileBackend.close(fileInputStream); @@ -150,6 +157,7 @@ public class JingleSocks5Transport extends JingleTransport { fileOutputStream = file.createOutputStream(); if (fileOutputStream == null) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create output stream"); return; } double size = file.getExpectedSize(); @@ -160,6 +168,7 @@ public class JingleSocks5Transport extends JingleTransport { count = inputStream.read(buffer); if (count == -1) { callback.onFileTransferAborted(); + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": file ended prematurely with "+remainingSize+" bytes remaining"); return; } else { fileOutputStream.write(buffer, 0, count); @@ -173,10 +182,13 @@ public class JingleSocks5Transport extends JingleTransport { file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); callback.onFileTransmitted(file); } catch (FileNotFoundException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (IOException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } catch (NoSuchAlgorithmException e) { + Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } finally { FileBackend.close(fileOutputStream); -- cgit v1.2.3 From 8dfa701043d6e442f24edeb4fec48e9d07377a90 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 12:08:43 +0200 Subject: added a few location questions --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 51984c91..2f96a83a 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -29,7 +29,8 @@ public class UIHelper { private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( "where are you", //en - "where r u", //en + "where are you now", //en + "where are you right now", //en "whats your 20", //en "what is your 20", //en "what's your 20", //en @@ -37,9 +38,13 @@ public class UIHelper { "what is your twenty", //en "what's your twenty", //en "wo bist du", //de - "wo sind sie", //de + "wo bist du jetzt", //de + "wo bist du gerade", //de "wo seid ihr", //de - "dónde estás" //es + "wo seid ihr jetzt", //de + "wo seid ihr gerade", //de + "dónde estás", //es + "donde estas" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE -- cgit v1.2.3 From b69ee7125d49493bea86c6e3095f1236ad895980 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 14 May 2015 15:25:52 +0200 Subject: Force Nameprepping of JID domain parts The IDN.toAscii()/IDN.toUnicode() family only namepreps the original domain passed to it if it contained non-ASCII characters. This means that for all-ASCII domains, no canonicalization is performed, which leads to issues like case-sensitivity. This workaround explicitly namepreps domain parts before calling IDN.toAscii() on them, in order to get a canonicalized representation (most notably, case invariance). A basic DB migration is also included. --- .../conversations/persistance/DatabaseBackend.java | 87 +++++++++++++++++++++- .../java/eu/siacs/conversations/xmpp/jid/Jid.java | 13 +++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 28e1c47e..ed88e434 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -4,11 +4,13 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Roster; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import android.content.Context; @@ -16,13 +18,14 @@ import android.database.Cursor; import android.database.sqlite.SQLiteCantOpenDatabaseException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 13; + private static final int DATABASE_VERSION = 14; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -130,6 +133,88 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("delete from "+Contact.TABLENAME); db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); } + if (oldVersion < 14 && newVersion >= 14) { + // migrate db to new, canonicalized JID domainpart representation + + // Conversation table + Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID " + +cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Conversation.UUID)), + }; + db.execSQL("update " + Conversation.TABLENAME + + " set " + Conversation.CONTACTJID + " = ? " + + " where " + Conversation.UUID + " = ?", updateArgs); + } + cursor.close(); + + // Contact table + cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Contact.JID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Contact JID " + +cursor.getString(cursor.getColumnIndex(Contact.JID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Contact.ACCOUNT)), + cursor.getString(cursor.getColumnIndex(Contact.JID)), + }; + db.execSQL("update " + Contact.TABLENAME + + " set " + Contact.JID + " = ? " + + " where " + Contact.ACCOUNT + " = ? " + + " AND " + Contact.JID + " = ?", updateArgs); + } + cursor.close(); + + // Account table + cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newServer; + try { + newServer = Jid.fromParts( + cursor.getString(cursor.getColumnIndex(Account.USERNAME)), + cursor.getString(cursor.getColumnIndex(Account.SERVER)), + "mobile" + ).getDomainpart(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Account SERVER " + +cursor.getString(cursor.getColumnIndex(Account.SERVER)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newServer, + cursor.getString(cursor.getColumnIndex(Account.UUID)), + }; + db.execSQL("update " + Account.TABLENAME + + " set " + Account.SERVER + " = ? " + + " where " + Account.UUID + " = ?", updateArgs); + } + cursor.close(); + } } public static synchronized DatabaseBackend getInstance(Context context) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java index 295e067a..f989c0c2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java @@ -130,12 +130,19 @@ public final class Jid { if (resourcepart.isEmpty() || resourcepart.length() > 1023) { throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH); } - dp = IDN.toUnicode(jid.substring(domainpartStart, slashLoc), IDN.USE_STD3_ASCII_RULES); + try { + dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, slashLoc)), IDN.USE_STD3_ASCII_RULES); + } catch (final StringprepException e) { + throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); + } finaljid = finaljid + dp + "/" + rp; } else { resourcepart = ""; - dp = IDN.toUnicode(jid.substring(domainpartStart, jid.length()), - IDN.USE_STD3_ASCII_RULES); + try{ + dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, jid.length())), IDN.USE_STD3_ASCII_RULES); + } catch (final StringprepException e) { + throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e); + } finaljid = finaljid + dp; } -- cgit v1.2.3 From b6a7e56bf667cfc0845ca0d50d88a77c43d9a27d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 13:58:11 +0200 Subject: call StartConversationActivity in init mode only after adding the first account --- src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java | 4 +++- .../java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 7aa7b1c2..931a1a2f 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -223,7 +223,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (avatar != null) { intent = new Intent(getApplicationContext(), StartConversationActivity.class); - intent.putExtra("init",true); + if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { + intent.putExtra("init", true); + } } else { intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index e8ab8dae..4333dbdb 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -116,7 +116,9 @@ public class PublishProfilePictureActivity extends XmppActivity { if (mInitialAccountSetup) { Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class); - intent.putExtra("init",true); + if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { + intent.putExtra("init", true); + } startActivity(intent); } finish(); -- cgit v1.2.3 From 4151b72a6e68faff45e3d166823459eaa07c63a3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 04:12:53 +0200 Subject: let jingle connection and manager handle message status --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 ---- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 4 ++++ .../eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4f2697a3..63d9ba7a 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -349,7 +349,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_FILE); - message.setStatus(Message.STATUS_OFFERED); String path = getFileBackend().getOriginalPath(uri); if (path!=null) { message.setRelativeFilePath(path); @@ -392,7 +391,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_IMAGE); - message.setStatus(Message.STATUS_OFFERED); new Thread(new Runnable() { @Override @@ -813,7 +811,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Presences presences = contact.getPresences(); if ((message.getCounterpart() != null) && (presences.has(message.getCounterpart().getResourcepart()))) { - markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } else { if (presences.size() == 1) { @@ -823,7 +820,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } catch (InvalidJidException e) { return; } - markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 4847d5f1..6c42d3d2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -271,6 +271,9 @@ public class JingleConnection implements Downloadable { this.mergeCandidates(JingleCandidate.parse(content.socks5transport() .getChildren())); this.fileOffer = packet.getJingleContent().getFileOffer(); + + mXmppConnectionService.sendIqPacket(account,packet.generateResponse(IqPacket.TYPE.RESULT),null); + if (fileOffer != null) { Element fileSize = fileOffer.findChild("size"); Element fileNameElement = fileOffer.findChild("name"); @@ -381,6 +384,7 @@ public class JingleConnection implements Downloadable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() != IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer"); mJingleStatus = JINGLE_STATUS_INITIATED; mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED); } else { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 5dfa3ff4..c19dd04c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -9,6 +9,7 @@ import android.annotation.SuppressLint; import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; @@ -58,7 +59,12 @@ public class JingleConnectionManager extends AbstractConnectionManager { } public JingleConnection createNewConnection(Message message) { + Downloadable old = message.getDownloadable(); + if (old != null) { + old.cancel(); + } JingleConnection connection = new JingleConnection(this); + mXmppConnectionService.markMessage(message,Message.STATUS_WAITING); connection.init(message); this.connections.add(connection); return connection; -- cgit v1.2.3 From b4a8984b18bed5673284d5fa4a5fcc256386d542 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 10:19:05 +0200 Subject: pulled new translations from transifex --- src/main/res/values-ca/strings.xml | 34 +++- src/main/res/values-pl/strings.xml | 25 +++ src/main/res/values-zh-rCN/strings.xml | 295 +++++++++++++++++++++++++++------ 3 files changed, 302 insertions(+), 52 deletions(-) diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml index a0861b16..9583932b 100644 --- a/src/main/res/values-ca/strings.xml +++ b/src/main/res/values-ca/strings.xml @@ -24,8 +24,8 @@ Escollir un contacte LLista bloqueix Ara - 1 min avans - %de minuts avans + 1 min abans + %de minuts abans Converses sense llegir o no llegides enviant… Desxifrant missatge. Espera si us plau… @@ -359,6 +359,7 @@ No s\'ha pogut canviar la contrasenya Començar a enviar un missatge de conversació xifrat Fer una pregunta + Si vosté i el seu contacte tenen un secret en comú que ningú més sap (com una broma o simplement el que vau dinar l\'última vegada que es van trobar) pot utilitzar aquest secret per comprovar les empremtes de cadascú.\n\nProporcionaràs una pista o una pregunta a la que el seu contacte donarà una resposta, que distingeix entre majúscules i minúscules. El seu contacte l\'hi agradaria verificar la seva empremta digital per un repte amb un secret compartit.El seu contacte proporciona el següent suggeriment o pregunta per aquest secret. El seu suggeriment no pot estar buit El teu secret compartit no pot estar buit @@ -416,4 +417,33 @@ Enviant %s Oferint %s Amaga el fora de línia + Deshabilita el compte + %s està escrivint... + %s ha deixat d\'escriure + Notificacions d\'escriptura + Permet el teu contacte saber quan estàs escrivint un missatge nou + Enviar localització + Mostrar localització + No s\'ha trobat cap aplicació per mostrar la localització + Localització + Localització rebuda + Conversa tancada + S\'ha sortit de la conferència + Opcions de certificats + No confiar en les CAs del sistema + Tots els certificats han de ser aprovats manualment + Eliminar certificats + Esborrar certificats aprovats manualment + No hi ha certificats aprovats manualment + Esborrar certificats + Esborrar selecció + Cancel·lar + + %d certificat esborrat + %d certificats esborrats + + + Seleccionar %d contacte + Seleccionar %d contactes + diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index e1849357..70c3a49d 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -202,6 +202,7 @@ Wiadomość zaszyfrowana. Zainstaluj OpenKeychain, żeby odszyfrować. Nieznany odcisk klucza OTR Znaleziono wiadomości zaszyfrowane przez OpenPGP + Odbiór nieudany Twój odcisk klucza Odcisk klucza OTR Weryfikuj @@ -236,7 +237,9 @@ Serwer odrzucił żądanie publikacji Wystąpił błąd podczas konwersji obrazu Nie udało się zapisać obrazu w pamięci urządzenia + (lub przytrzymaj długo, aby ustawić domyślny) Serwer nie udostępnia możliwości publikacji awatarów + szepcze do %s Wyślij prywatną wiadomość do %s Połącz @@ -252,10 +255,12 @@ Konferencja jest zabezpieczona hasłem Wprowadź hasło Kontakt nie udostępnia powiadomień o obecności + Poproś kontakt o udostępnienie powiadomień o obecności.\n\nPozwoli to na ustalenie klienta, z którego korzysta rozmówca. Zażądaj teraz Usuń odcisk klucza Czy na pewno chcesz usunąć odcisk klucza? Ignoruj + Uwaga: Wysyłanie bez obustronnych powiadomień o obecności może powodować nieoczekiwane problemy.\n\nSprawdź subskrypcję powiadomień w szczegółach kontaktu. Ustawienia szyfrowania Wymuszaj szyfrowanie typu end-to-end Szyfruj wszystkie wiadomości (poza konferencjami) @@ -283,6 +288,7 @@ Zbanowano cię w konferencji To jest zamknięty pokój Wyrzucono cię z konferencji + używając konta %s Sprawdzanie obrazka na hoście HTTP Obraz został usunięty Brak połączenia. Spróbuj ponownie później @@ -302,6 +308,7 @@ Szczegóły konta Weryfikuj OTR Zdalny odcisk klucza + skanuj (lub zetknij telefony) Protokół socialist millionaire Podpowiedź lub pytanie @@ -309,6 +316,7 @@ Potwierdź W toku Odpowiedz + Operacja nieudana Sekrety są niezgodne Spróbuj ponownie Zakończ @@ -382,6 +390,7 @@ Konferencja prywatna, dla zaakceptowanych uczestników Opcje konferencji Prywatna (tylko zaakceptowani) + Nieanonimowa Opcje konferencji zostały zmienione! Nie udało się zmienić opcji konferencji Nigdy @@ -420,7 +429,23 @@ Otrzymano lokalizację Zamknięto konwersację Opuszczono konferencję + Ustawienia certyfikatów Nie ufaj certyfikatom systemowym Wymagaj ręcznego potwierdzania certyfikatów + Usuń certyfikat + Wybierz zaufane certyfikaty do usunięcia + Brak ręcznie zaufanych certyfikatów + Usuń certyfikaty + Usuń zaznaczone Anuluj + + Usunięto %d certyfikat + Usunięto %d certyfikaty + Usunięto %d certyfikatów + + + %d kontakt wybrany + %d kontakty wybrane + %d kontaktów wybranych + diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 49ca9b97..2f80e064 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -11,6 +11,10 @@ 编辑姓名 添加到手机通讯录 从列表中删除 + 屏蔽联系人 + 解除联系人屏蔽 + 屏蔽域名 + 解除域名屏蔽 管理账户 设置 讨论组详情 @@ -18,6 +22,7 @@ 分享会话 开始会话 选择联系人 + 屏蔽列表 刚刚 1 分钟前 %d分钟前 @@ -30,56 +35,65 @@ 版主 参与者 访客 - 将 %s从列表中移除? 与该联系人的会话消息不会清除. - 从书签中移除 %s?相关会话消息不会被清除 . + 将 %s 从列表中移除? 与该联系人的会话消息不会清除. + 你想屏蔽 %s 将不能发送信息给你? + 你想解除对 %s 的屏蔽吗,他们将可以发送信息给你? + 屏蔽 %s 中的所有联系人? + 解除对 %s 中所有联系人的屏蔽? + 联系人已屏蔽 + 从书签中移除 %s ?相关会话消息不会被清除 . 在服务器上注册新账户 + 在服务器上改变密码 分享 开始会话 邀请联系人 联系人 取消 + 设置 添加 编辑 删除 + 屏蔽 + 解除屏蔽 保存 完成 - Conversations停止运行 - 发送堆栈跟踪到正在开发Conversations的人员\n警告: 该操作将用您的 XMPP账户发送堆栈跟踪到开发人员. + Conversations 崩溃 + 发送堆栈跟踪信息到 Conversations 的开发人员\n警告: 该操作将用您的 XMPP 账户发送堆栈跟踪给开发人员。 现在发送 不再询问 无法连接至账户 无法连接至多个账户 点击此处管理账户 - 附件 - 该联系人不在您的列表.需要加为联系人吗 ? + 附加文件 + 该联系人不在您的列表。需要加为联系人吗 ? 添加联系人 传递失败 拒绝 准备传输图像 清除历史记录 清除会话记录 - 删除该会话中所有信息?\n\n注: 该操作不会影响其他设备或服务器保存的信息. + 删除该会话中所有信息?\n\n注: 该操作不会影响其他设备或服务器保存的信息。 删除消息 之后结束该会话 添加在线用户至联系人 发送纯文本信息 发送 OTR 加密信息 发送 OpenPGP 加密信息 - 用户名修改成功 + 昵称修改成功 下载图片 不加密发送 - 解密失败,可能是私钥不正确. + 解密失败,可能是私钥不正确。 OpenKeychain - 会话运用了第三方app,名为 OpenKeychain 用来加密、解码信息以及管理您的公钥.\n\nOpenKeychain 遵循 GPLv3 并且在 F-Droid和Google Play上可操作.\n\n(之后请重启conversations.) + 会话运用了第三方app,名为 OpenKeychain 用来加密、解密信息以及管理您的密钥。\n\nOpenKeychain 遵循 GPLv3 并且可以在 F-Droid 和 Google Play 上获取。\n\n(之后请重启 conversations) 重启 安装 输入… 等待… - 未发现OpenPGP 密码 - 会话加密信息失败,因为联系人未告知他/她的公钥.\n\n请通知联系人设置 OpenPGP. - 未找到 OpenPGP 密码 + 未发现 OpenPGP 密钥 + 会话加密信息失败,因为联系人未提供他/她的公钥。\n\n请通知联系人设置 OpenPGP。 + 未找到 OpenPGP 密钥 因您的联系人未公布公钥,Conversations未能成功加密您的信息.\n\n请通知联系人设置OpenPGP. - 加密信息已接收.点击进行解密和查看. + 加密信息已接收。点击解密并查看。 常规 XMPP 资源 客户端标识名称 @@ -91,41 +105,41 @@ 震动 收到新消息时震动 声音 - 收到新消息时播放铃声 + 收到新消息时的铃声 讨论组通知 当有新的消息时总是通知而不是亮屏时才通知 通知限期 接收副本短时间内关闭通知 高级选项 - 总不发送故障报告 - 发送堆栈跟踪帮助Conversations开发人员 + 总不发送崩溃报告 + 发送堆栈跟踪帮助 Conversations 开发人员 确认消息 当你已收到消息并且已阅时通知好友 - UI选项 + UI 选项 OpenKeychain 报告了一个错误 - 解码文件时出现I/O错误 + 解密文件时出现 I/O 错误 接受 产生了一个错误 同意更新在线联系人 - 预先同意并请求您的联系人进行更新 + 预先同意并请求更新您的联系人 关注 你的账号 - Keys - 发送在线联系人更新列表 - 接收在线联系人更新列表 - 请求在线联系人更新列表 + 密钥 + 发送在线联系人列表更新 + 接收在线联系人列表更新 + 请求在线联系人列表更新 选择图片 照相 预先同意订阅请求 您选择的文件不是图像文件 转换图像出错 未找到文件 - 常规的I/O错误.可能是存储空间不足的原因? - 您用来选择图片的app没有给予足够权限支持我们读取文件.\n\n请使用另一文件管理器选择图片 + 常规的 I/O 错误。可能是存储空间不足? + 您用来选择图片的 app 没有给予足够权限支持我们读取文件。\n\n请使用另一文件管理器选择图片 未知 暂时不可用 在线 - Connecting\u2026 + 连接中\u2026 离线 未授权 未找到服务器 @@ -134,6 +148,8 @@ 用户名已存在 注册完成 服务器不支持注册 + 安全错误 + 服务器不兼容 纯文本内容 OTR OpenPGP @@ -141,11 +157,11 @@ 删除账号 暂时不可用 发布头像 - 发布 OpenPGP 公共秘钥 + 发布 OpenPGP 公钥 启用账户 确定? 如果删除用户,所有会话信息将会丢失 - Record voice 录音 + 录音 Jabber ID 密码 username@example.com @@ -153,23 +169,28 @@ 密码 确认密码 密码不一致 - 该Jabber ID 无效 - 空间不足,图片过大 + 该 Jabber ID 无效 + 空间不足。图片过大 您将添加 %s 至手机联系人列表? 在线 - 免费对话 + 自由畅聊 离开 长时间离开 请勿打扰 离线 讨论组 其他成员 + 服务器信息 + XEP-0313: MAM XEP-0280: 消息碳 + XEP-0352: 客户端状态指示 + XEP-0191: 屏蔽指令 + XEP-0237: 花名册版本 XEP-0198: 流管理 XEP-0163: PEP (头像) 有效 无效 - 缺少公共秘钥公告 + 缺少公钥通知 最近一次查看为刚刚 最近一次查看为一分钟前 最近一次查看为 %d 分钟前 @@ -178,9 +199,9 @@ 最近一次查看为一天前 最近一次查看为 %d天前 未曾查看 - 加密信息. 请安装OpenKeychain进行解码. - 未知 OTR指纹 - OpenPGP 发现加密信息 + 加密信息. 请安装 OpenKeychain 以解密。 + 未知 OTR 指纹 + 发现 OpenPGP 加密信息 接收失败 你的指纹 OTR 指纹 @@ -192,6 +213,8 @@ 加入讨论组 删除联系人 查看联系人详细信息 + 屏蔽联系人 + 解除联系人屏蔽 创建 联系人已存在 加入 @@ -200,26 +223,26 @@ 保存为书签 删除书签 该书签已存在 - 你的 + 编辑讨论组主题 讨论组未找到 离开 联系人已添加你到联系人列表 反向添加 - 目前读到%s 处 + 目前读到 %s 处 发布 - 点击头像可选择头像 - 请注意: 所有关注您最新动态的人将看到该图像. - 发布… + 点击头像可从相册中选择头像 + 请注意: 所有关注您最新动态的人将看到该图像。 + 正在发布… 服务器拒绝了您的发布请求 - 转换头像出错 - 不能将头像保存至disk + 转换头像图片出错 + 不能将头像保存至磁盘 (或长按按钮将返回默认头像) 您的服务器不支持发布头像 密谈 至 %s - 发送私密消息到%s - Connect + 发送私密消息到 %s + 连接 该账号已存在 下一步 当前会话已建立 @@ -232,21 +255,193 @@ 讨论组设有密码 输入密码 缺少在线联系人更新 - 请先发送更新在线联系人请求.\n\n这将用来判断您的联系人所用的客户端类型人. + 请先发送更新在线联系人的请求。\n\n以判断您的联系人所用的客户端类型。 现在发送请求 删除指纹 是否确定删除该指纹? 忽略 - 警告:在没有相互更新在线联系人的情况下发送将会出现未知问题.\n\n到联系人详情确认您订阅的在线联系人. + 警告:在没有相互更新在线联系人的情况下发送将会出现未知问题。\n\n前往联系人详情以验证您订阅的在线联系人。 加密设置 - 强制要求 end-to-end 加密 + 强制要求端对端加密 总是发送加密信息(讨论组信息除外) 不保存加密信息 警告:此操作将会导致信息丢失 - Expert 选项 + 导出选项 请谨慎使用 + 关于 Conversations + 构建及许可证信息 + 静默时间段 + 开始时间 + 结束时间 + 启用静默时间段 + 在静默时间段内通知将保持静音 放大字体 - 整个app界面使用更大号的字体 + 整个 app 界面使用较大的字体 发送按钮显示状态 + 请求消息回复 + 如果支持消息将会以绿色对勾标识 发送按钮采用其他颜色以示发送状态的区别 + 其他 + 讨论组名称 + 用讨论组的主题来标示讨论组而不是 JID + OTR 指纹已拷贝到剪贴板! + 你被此讨论组屏蔽 + 此讨论组只允许成员加入 + 你被从此讨论组踢出 + 用账户 %s + 正在 HTTP 托管中检查图片 + 此图片已经被删除 + 你没有连接。请稍后重试 + 检查图片文件尺寸 + 消息选项 + 拷贝文本 + 拷贝原始URL + 再次发送 + 图片 URL + 消息文本 + 已经拷贝 URL 到剪贴板 + 消息已经拷贝到剪贴板 + 图片传送失败 + 扫描二维码 + 显示二维码 + 显示屏蔽列表 + 账户详情 + 验证 OTR + 远程指纹 + 扫描 + (或轻触手机) + Socialist Millionaire Protocol + 提示或问题 + 共知的秘密 + 确认 + 处理中 + 回应 + 失败 + 秘密不符 + 再试一遍 + 完成 + 验证通过! + 联系人请求 SMP 验证 + 没有找到 OTR 会话 + Conversations + 保持前台服务 + 防止操作系统中断你的连接 + 关闭文件 + 接收中 %1$s (已完成 %2$d%%) + 下载 %s + 文件 + 打开 %s + 发送中 (已完成 %1$d%%) + 准备传送文件 + 可以下载 %s + 取消传送 + 文件传送失败 + 文件已经删除 + 没有可以打开此文件的应用 + 不能验证指纹 + 手工验证 + 你确认验证你的联系人的 OTR 指纹? + 现实动态标签 + 在联系人下方显示只读标签 + 启用通知 + 与…创建讨论组 + 无法找到讨论组服务器 + 讨论组创建失败! + 讨论组已创建! + 秘密被接受! + 重置 + 账户头像 + 拷贝 OTR 指纹到剪贴板 + 从服务器获取历史记录 + 服务器上没有更多历史记录 + 更新中… + 密码已修改! + 不能修改密码 + 要启动加密聊天先发送一条消息 + 提出问题 + 如果你和你的联系人有一个共知的秘密(比如一个内部笑话或者仅仅只是上次见面时吃的午餐) 你可以使用这个秘密来验证彼此的指纹。\n\n你的联系人将以大小写敏感的方式给出答案,你可以给出提示或问题。 + 你的联系人可以通过一个你们共知的秘密来验证指纹。你的联系人给出了如下的提示或问题。 + 你的提示不能为空 + 你共知的秘密不能为空 + 请仔细核对下面显示出来的你的联系人的指纹。\n你可以使用任何可信赖的联系方式,比如加密邮件或电话,来交换这些指纹信息。 + 修改密码 + 当前密码 + 新密码 + 密码不能为空 + 启用所有账户 + 禁用所有账户 + 做一个动作和 + 没有从属关系 + 没有角色 + 抛弃 + 成员 + 高级模式 + 已授予的成员 + 吊销的成员 + 授予管理员权限 + 吊销管理员权限 + 从讨论组移出 + 不能修改 %s 的从属关系 + 屏蔽出讨论组 + 你正尝试将 %s 移出一个公共的讨论组。唯一的方式是永远屏蔽这个用户 + 现在屏蔽 + 不能修改 %s 的角色 + 公开访问的讨论组 + 私密,只有成员可以加入的讨论组 + 讨论组选项 + 私密(只对成员开放) + 非匿名 + 讨论组选项已修改! + 不能修改讨论组选项 + 从不 + 30 分钟 + 1 个小时 + 2 个小时 + 8 个小时 + 直到新的通知 + 输入选项 + 回车是发送 + 用回车键来发送消息 + 显示回车键 + 改变表情键为回车键 + 音频 + 视频 + 图像 + PDF 文档 + Android App + 联系人 + 已经收到 %s + 禁用前端服务 + 轻触打开 Conversations + 头像已经发布! + 发送中 %s + 提供中 %s + 隐藏离线联系人 + 禁用账户 + %s 正在输入… + %s 已停止输入 + 键盘输入通知 + 让对方知道你正在输入新消息 + 发送位置 + 显示位置 + 无法找到显示位置的应用 + 位置 + 位置已收到 + Conversation 已关闭 + 离开讨论组 + 证书选项 + 不相信系统 CA + 所有证书必须人工通过 + 移除证书 + 删除人工通过的证书 + 没有人工通过的证书 + 移除证书 + 删除选项 + 取消 + + %d 个证书已被删除 + + + 选择 %d 个联系人 + -- cgit v1.2.3 From 7ccdc772edccb2cd71150441cf21dbcab7e6e7d9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 10:19:19 +0200 Subject: version bump to 1.4.0-beta --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c47e6ee1..595ff0ee 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 64 - versionName "1.4.0-alpha3" + versionCode 65 + versionName "1.4.0-beta" } compileOptions { -- cgit v1.2.3 From fce30f22c9c75fb4bc12992e6d7e7161ce5148b1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 12:49:04 +0200 Subject: made white space check in bodyContainsDownloadable less aggresive --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index a8bb9c55..38152edb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -440,7 +440,7 @@ public class Message extends AbstractEntity { * "http://example.com/image.jpg text that will not be shown /abc.png" * or more than one image link in one message. */ - if (body.contains(" ")) { + if (body.trim().contains(" ")) { return false; } try { -- cgit v1.2.3 From d672d578c91f54e17b930c4a08d133095a863d52 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 17 May 2015 12:32:04 +0200 Subject: fixed crash on failed account registry --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 6c67c072..b0d8272d 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -683,7 +683,7 @@ public class XmppConnection implements Runnable { disconnect(true); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not register. instructions are" - + instructions != null ? instructions.getContent() : ""); + + (instructions != null ? instructions.getContent() : "")); } } }); -- cgit v1.2.3 From 34545aa96fc3148d7fb038109c99841ee4d16690 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 08:36:37 +0200 Subject: added changelog for upcoming 1.4.0 release --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae267086..61980b61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ###Changelog +####Version 1.4.0 +* send button turns into quick action button to offer faster access to take photo, send location or record audio +* visually seperate merged messages +* faster reconnects of failed accounts after network switches +* r/o vcard avatars for contacts +* various bug fixes + ####Version 1.3.0 * swipe conversations to end them * quickly enable / disable account via slider -- cgit v1.2.3 From fbc43a8d38e62fc2a3b60e7c363c8fe1e2668cc6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 03:17:14 +0200 Subject: don't offer initiator his own candidates --- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 6c42d3d2..c9bb9c93 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -213,7 +213,7 @@ public class JingleConnection implements Downloadable { @Override public void onPrimaryCandidateFound(boolean success, - final JingleCandidate candidate) { + final JingleCandidate candidate) { if (success) { final JingleSocks5Transport socksConnection = new JingleSocks5Transport( JingleConnection.this, candidate); @@ -399,7 +399,9 @@ public class JingleConnection implements Downloadable { private List getCandidatesAsElements() { List elements = new ArrayList<>(); for (JingleCandidate c : this.candidates) { - elements.add(c.toElement()); + if (c.isOurs()) { + elements.add(c.toElement()); + } } return elements; } -- cgit v1.2.3 From 1446a59fa594be49277d1ec9d7fe023949bcfc55 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 04:34:34 +0200 Subject: use a 20s timeout on socks5 connections --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 9f5d14fd..050116b5 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -11,6 +11,7 @@ public final class Config { public static final int PING_MAX_INTERVAL = 300; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 10; + public static final int SOCKET_TIMEOUT = 20; public static final int CONNECT_TIMEOUT = 90; public static final int CARBON_GRACE_PERIOD = 60; public static final int MINI_GRACE_PERIOD = 750; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 35375a5d..8d74f44e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -6,7 +6,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -56,8 +58,9 @@ public class JingleSocks5Transport extends JingleTransport { @Override public void run() { try { - socket = new Socket(candidate.getHost(), - candidate.getPort()); + socket = new Socket(); + SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort()); + socket.connect(address,Config.SOCKET_TIMEOUT * 1000); inputStream = socket.getInputStream(); outputStream = socket.getOutputStream(); byte[] login = { 0x05, 0x01, 0x00 }; -- cgit v1.2.3 From a0575c81abf9b8b56a3b47753b373218a655c608 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 18 May 2015 08:48:08 +0200 Subject: use same socket time out for jingle and xmpp connections --- src/main/java/eu/siacs/conversations/Config.java | 2 +- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 050116b5..779cbbe8 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -11,7 +11,7 @@ public final class Config { public static final int PING_MAX_INTERVAL = 300; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 10; - public static final int SOCKET_TIMEOUT = 20; + public static final int SOCKET_TIMEOUT = 15; public static final int CONNECT_TIMEOUT = 90; public static final int CARBON_GRACE_PERIOD = 60; public static final int MINI_GRACE_PERIOD = 750; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index b0d8272d..9bda3c09 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -187,7 +187,7 @@ public class XmppConnection implements Runnable { + srvRecordServer + ":" + srvRecordPort); } socket = new Socket(); - socket.connect(addr, 20000); + socket.connect(addr, Config.SOCKET_TIMEOUT * 1000); socketError = false; } catch (final UnknownHostException e) { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); -- cgit v1.2.3 From bb603644880f0b32d8a7b54d5158f6fac678aa12 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 19 May 2015 08:31:56 +0200 Subject: hide block contact from context menu when server feature is not available fixed #1207 --- .../java/eu/siacs/conversations/ui/StartConversationActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index a556b8b7..7863ff94 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -65,6 +65,7 @@ import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.ListItemAdapter; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -757,14 +758,16 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } else { activity.contact_context_id = acmi.position; final Blockable contact = (Contact) activity.contacts.get(acmi.position); - final MenuItem blockUnblockItem = menu.findItem(R.id.context_contact_block_unblock); - if (blockUnblockItem != null) { + XmppConnection xmpp = contact.getAccount().getXmppConnection(); + if (xmpp != null && xmpp.getFeatures().blocking()) { if (contact.isBlocked()) { blockUnblockItem.setTitle(R.string.unblock_contact); } else { blockUnblockItem.setTitle(R.string.block_contact); } + } else { + blockUnblockItem.setVisible(false); } } } -- cgit v1.2.3 From 73a4ffefdf470be517eb32bc43bb93c3dff72b38 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 03:27:52 +0200 Subject: added fall back package id for voice recorder plugin --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a2a405c3..1b5e5178 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -429,6 +429,7 @@ public class ConversationActivity extends XmppActivity break; case ATTACHMENT_CHOICE_RECORD_VOICE: intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + fallbackPackageId = "eu.siacs.conversations.voicerecorder"; break; case ATTACHMENT_CHOICE_LOCATION: intent.setAction("eu.siacs.conversations.location.request"); -- cgit v1.2.3 From 7824c01748a89688c5f76307cc1f4221a9e2ffb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 May 2015 03:36:10 +0200 Subject: version bump to 1.4.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 595ff0ee..98b341d5 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 21 - versionCode 65 - versionName "1.4.0-beta" + versionCode 66 + versionName "1.4.0" } compileOptions { -- cgit v1.2.3