1package eu.siacs.conversations.utils;
2
3import java.io.FileNotFoundException;
4import java.util.ArrayList;
5import java.util.Calendar;
6import java.util.Date;
7import java.util.List;
8import java.util.Locale;
9import java.util.regex.Pattern;
10
11import eu.siacs.conversations.R;
12import eu.siacs.conversations.entities.Account;
13import eu.siacs.conversations.entities.Contact;
14import eu.siacs.conversations.entities.Conversation;
15import eu.siacs.conversations.entities.MucOptions.User;
16import eu.siacs.conversations.ui.ConversationActivity;
17import eu.siacs.conversations.ui.ManageAccountActivity;
18import android.annotation.SuppressLint;
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.app.Notification;
22import android.app.NotificationManager;
23import android.app.PendingIntent;
24import android.content.Context;
25import android.content.DialogInterface;
26import android.content.DialogInterface.OnClickListener;
27import android.content.Intent;
28import android.graphics.Bitmap;
29import android.graphics.BitmapFactory;
30import android.graphics.Canvas;
31import android.graphics.Paint;
32import android.graphics.Rect;
33import android.graphics.Typeface;
34import android.net.Uri;
35import android.provider.ContactsContract.Contacts;
36import android.support.v4.app.NotificationCompat;
37import android.support.v4.app.TaskStackBuilder;
38import android.text.format.DateFormat;
39import android.text.format.DateUtils;
40import android.util.DisplayMetrics;
41import android.view.LayoutInflater;
42import android.view.View;
43import android.widget.QuickContactBadge;
44import android.widget.TextView;
45
46public class UIHelper {
47 private static final int BG_COLOR = 0xFF181818;
48 private static final int FG_COLOR = 0xFFFAFAFA;
49 private static final int TRANSPARENT = 0x00000000;
50 private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE
51 | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL;
52 private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME
53 | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE;
54
55 public static String readableTimeDifference(Context context, long time) {
56 return readableTimeDifference(context, time, false);
57 }
58
59 public static String readableTimeDifferenceFull(Context context, long time) {
60 return readableTimeDifference(context, time, true);
61 }
62
63 private static String readableTimeDifference(Context context, long time,
64 boolean fullDate) {
65 if (time == 0) {
66 return context.getString(R.string.just_now);
67 }
68 Date date = new Date(time);
69 long difference = (System.currentTimeMillis() - time) / 1000;
70 if (difference < 60) {
71 return context.getString(R.string.just_now);
72 } else if (difference < 60 * 2) {
73 return context.getString(R.string.minute_ago);
74 } else if (difference < 60 * 15) {
75 return context.getString(R.string.minutes_ago,
76 Math.round(difference / 60.0));
77 } else if (today(date)) {
78 java.text.DateFormat df = DateFormat.getTimeFormat(context);
79 return df.format(date);
80 } else {
81 if (fullDate) {
82 return DateUtils.formatDateTime(context, date.getTime(),
83 FULL_DATE_FLAGS);
84 } else {
85 return DateUtils.formatDateTime(context, date.getTime(),
86 SHORT_DATE_FLAGS);
87 }
88 }
89 }
90
91 private static boolean today(Date date) {
92 Calendar cal1 = Calendar.getInstance();
93 Calendar cal2 = Calendar.getInstance();
94 cal1.setTime(date);
95 cal2.setTimeInMillis(System.currentTimeMillis());
96 return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
97 && cal1.get(Calendar.DAY_OF_YEAR) == cal2
98 .get(Calendar.DAY_OF_YEAR);
99 }
100
101 public static String lastseen(Context context, long time) {
102 if (time == 0) {
103 return context.getString(R.string.never_seen);
104 }
105 long difference = (System.currentTimeMillis() - time) / 1000;
106 if (difference < 60) {
107 return context.getString(R.string.last_seen_now);
108 } else if (difference < 60 * 2) {
109 return context.getString(R.string.last_seen_min);
110 } else if (difference < 60 * 60) {
111 return context.getString(R.string.last_seen_mins,
112 Math.round(difference / 60.0));
113 } else if (difference < 60 * 60 * 2) {
114 return context.getString(R.string.last_seen_hour);
115 } else if (difference < 60 * 60 * 24) {
116 return context.getString(R.string.last_seen_hours,
117 Math.round(difference / (60.0 * 60.0)));
118 } else if (difference < 60 * 60 * 48) {
119 return context.getString(R.string.last_seen_day);
120 } else {
121 return context.getString(R.string.last_seen_days,
122 Math.round(difference / (60.0 * 60.0 * 24.0)));
123 }
124 }
125
126 public static void showErrorNotification(Context context,
127 List<Account> accounts) {
128 NotificationManager mNotificationManager = (NotificationManager) context
129 .getSystemService(Context.NOTIFICATION_SERVICE);
130 List<Account> accountsWproblems = new ArrayList<Account>();
131 for (Account account : accounts) {
132 if (account.hasErrorStatus()) {
133 accountsWproblems.add(account);
134 }
135 }
136 NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
137 context);
138 if (accountsWproblems.size() == 0) {
139 mNotificationManager.cancel(1111);
140 return;
141 } else if (accountsWproblems.size() == 1) {
142 mBuilder.setContentTitle(context
143 .getString(R.string.problem_connecting_to_account));
144 mBuilder.setContentText(accountsWproblems.get(0).getJid());
145 } else {
146 mBuilder.setContentTitle(context
147 .getString(R.string.problem_connecting_to_accounts));
148 mBuilder.setContentText(context.getString(R.string.touch_to_fix));
149 }
150 mBuilder.setOngoing(true);
151 mBuilder.setLights(0xffffffff, 2000, 4000);
152 mBuilder.setSmallIcon(R.drawable.ic_notification);
153 TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
154 stackBuilder.addParentStack(ConversationActivity.class);
155
156 Intent manageAccountsIntent = new Intent(context,
157 ManageAccountActivity.class);
158 stackBuilder.addNextIntent(manageAccountsIntent);
159
160 PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
161 PendingIntent.FLAG_UPDATE_CURRENT);
162
163 mBuilder.setContentIntent(resultPendingIntent);
164 Notification notification = mBuilder.build();
165 mNotificationManager.notify(1111, notification);
166 }
167
168 @SuppressLint("InflateParams")
169 public static AlertDialog getVerifyFingerprintDialog(
170 final ConversationActivity activity,
171 final Conversation conversation, final View msg) {
172 final Contact contact = conversation.getContact();
173 final Account account = conversation.getAccount();
174
175 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
176 builder.setTitle("Verify fingerprint");
177 LayoutInflater inflater = activity.getLayoutInflater();
178 View view = inflater.inflate(R.layout.dialog_verify_otr, null);
179 TextView jid = (TextView) view.findViewById(R.id.verify_otr_jid);
180 TextView fingerprint = (TextView) view
181 .findViewById(R.id.verify_otr_fingerprint);
182 TextView yourprint = (TextView) view
183 .findViewById(R.id.verify_otr_yourprint);
184
185 jid.setText(contact.getJid());
186 fingerprint.setText(conversation.getOtrFingerprint());
187 yourprint.setText(account.getOtrFingerprint());
188 builder.setNegativeButton("Cancel", null);
189 builder.setPositiveButton("Verify", new OnClickListener() {
190
191 @Override
192 public void onClick(DialogInterface dialog, int which) {
193 contact.addOtrFingerprint(conversation.getOtrFingerprint());
194 msg.setVisibility(View.GONE);
195 activity.xmppConnectionService.syncRosterToDisk(account);
196 }
197 });
198 builder.setView(view);
199 return builder.create();
200 }
201
202 private final static class EmoticonPattern {
203 Pattern pattern;
204 String replacement;
205
206 EmoticonPattern(String ascii, int unicode) {
207 this.pattern = Pattern.compile("(?<=(^|\\s))" + ascii
208 + "(?=(\\s|$))");
209 this.replacement = new String(new int[] { unicode, }, 0, 1);
210 }
211
212 String replaceAll(String body) {
213 return pattern.matcher(body).replaceAll(replacement);
214 }
215 }
216
217 private static final EmoticonPattern[] patterns = new EmoticonPattern[] {
218 new EmoticonPattern(":-?D", 0x1f600),
219 new EmoticonPattern("\\^\\^", 0x1f601),
220 new EmoticonPattern(":'D", 0x1f602),
221 new EmoticonPattern("\\]-?D", 0x1f608),
222 new EmoticonPattern(";-?\\)", 0x1f609),
223 new EmoticonPattern(":-?\\)", 0x1f60a),
224 new EmoticonPattern("[B8]-?\\)", 0x1f60e),
225 new EmoticonPattern(":-?\\|", 0x1f610),
226 new EmoticonPattern(":-?[/\\\\]", 0x1f615),
227 new EmoticonPattern(":-?\\*", 0x1f617),
228 new EmoticonPattern(":-?[Ppb]", 0x1f61b),
229 new EmoticonPattern(":-?\\(", 0x1f61e),
230 new EmoticonPattern(":-?[0Oo]", 0x1f62e),
231 new EmoticonPattern("\\\\o/", 0x1F631), };
232
233 public static String transformAsciiEmoticons(String body) {
234 if (body != null) {
235 for (EmoticonPattern p : patterns) {
236 body = p.replaceAll(body);
237 }
238 body = body.trim();
239 }
240 return body;
241 }
242}