Merge remote-tracking branch 'upstream/master' into lite

This commit is contained in:
adbenitez
2021-12-15 12:31:19 -05:00
73 changed files with 1863 additions and 1931 deletions
+1
View File
@@ -54,6 +54,7 @@ public class DcContact {
public native String getProfileImage();
public native int getColor ();
public native String getStatus ();
public native long getLastSeen ();
public native boolean isBlocked ();
public native boolean isVerified ();
+2
View File
@@ -115,6 +115,7 @@ public class DcContext {
public native void setStockTranslation (int stockId, String translation);
public native String getBlobdir ();
public native String getLastError ();
public native void configure ();
public native void stopOngoingProcess ();
public native int isConfigured ();
@@ -198,6 +199,7 @@ public class DcContext {
public native boolean wasDeviceMsgEverAdded(String label);
public DcLot checkQr (String qr) { return new DcLot(checkQrCPtr(qr)); }
public native String getSecurejoinQr (int chat_id);
public native String getSecurejoinQrSvg (int chat_id);
public native int joinSecurejoin (String qr);
public native void sendLocationsToChat (int chat_id, int seconds);
public native boolean isSendingLocationsToChat(int chat_id);
@@ -1552,7 +1552,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
// in-chat search
private int beforeSearchComposeVisibility = View.VISIBLE;
private int beforeSearchAttachVisibility = View.GONE;
private Menu searchMenu = null;
private int[] searchResult = {};
@@ -1578,16 +1577,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
beforeSearchComposeVisibility = composePanel.getVisibility();
composePanel.setVisibility(View.GONE);
beforeSearchAttachVisibility = attachmentManager.getVisibility();
attachmentManager.setVisibility(View.GONE);
ConversationActivity.this.makeSearchMenuVisible(menu, searchItem, true);
}
private void searchCollapse(final Menu menu, final MenuItem searchItem) {
searchMenu = null;
composePanel.setVisibility(beforeSearchComposeVisibility);
attachmentManager.setVisibility(beforeSearchAttachVisibility);
ConversationActivity.this.makeSearchMenuVisible(menu, searchItem, false);
}
@@ -191,7 +191,7 @@ public class ConversationFragment extends MessageSelectorFragment
noMessageTextView.setText(R.string.device_talk_explain);
}
else {
String message = getString(R.string.chat_no_messages_hint, dcChat.getName(), dcChat.getName());
String message = getString(R.string.chat_new_one_to_one_hint, dcChat.getName());
noMessageTextView.setText(message);
}
}
@@ -98,6 +98,10 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
msg.setText(getString(R.string.update_1_24_android) + " https://delta.chat/en/blog");
dcContext.addDeviceMsg("update_1_24n_android", msg); // addDeviceMessage() makes sure, messages with the same id are not added twice
msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT);
msg.setText(getString(R.string.update_1_26));
dcContext.addDeviceMsg("update_1_26c_android", msg); // addDeviceMessage() makes sure, messages with the same id are not added twice
// create view
setContentView(R.layout.conversation_list_activity);
@@ -116,7 +116,6 @@ public class ConversationListFragment extends Fragment
eventCenter.addObserver(DcContext.DC_EVENT_MSG_DELIVERED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_FAILED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_READ, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_READ, this);
eventCenter.addObserver(DcContext.DC_EVENT_CONNECTIVITY_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_SELFAVATAR_CHANGED, this);
}
@@ -135,19 +135,18 @@ public class ConversationListItem extends RelativeLayout
this.glideRequests = glideRequests;
int state = dcSummary.getState();
int unreadCount = ((state==DcMsg.DC_STATE_IN_FRESH || state==DcMsg.DC_STATE_IN_NOTICED) && !thread.isContactRequest())?
thread.getUnreadCount() : 0;
int unreadCount = thread.getUnreadCount();
if (highlightSubstring != null) {
this.fromView.setText(getHighlightedSpan(locale, recipient.getName(), highlightSubstring));
} else {
this.fromView.setText(recipient, unreadCount == 0);
this.fromView.setText(recipient, state!=DcMsg.DC_STATE_IN_FRESH);
}
this.subjectView.setText(thread.getDisplayBody());
this.subjectView.setTypeface(unreadCount == 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
this.subjectView.setTextColor(unreadCount == 0 ? ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_subject_color)
: ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_unread_color));
this.subjectView.setTypeface(state==DcMsg.DC_STATE_IN_FRESH ? BOLD_TYPEFACE : LIGHT_TYPEFACE);
this.subjectView.setTextColor(state==DcMsg.DC_STATE_IN_FRESH ? ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_unread_color)
: ThemeUtil.getThemedColor(getContext(), R.attr.conversation_list_item_subject_color));
if (thread.getDate() > 0) {
CharSequence date = DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, thread.getDate());
@@ -264,46 +263,39 @@ public class ConversationListItem extends RelativeLayout
{
requestBadgeView.setVisibility(View.GONE);
archivedBadgeView.setVisibility(View.GONE);
if (state==DcMsg.DC_STATE_IN_FRESH || state==DcMsg.DC_STATE_IN_NOTICED)
{
deliveryStatusIndicator.setNone();
if(unreadCount==0) {
unreadIndicator.setVisibility(View.GONE);
}
else {
unreadIndicator.setImageDrawable(TextDrawable.builder()
.beginConfig()
.width(ViewUtil.dpToPx(getContext(), 24))
.height(ViewUtil.dpToPx(getContext(), 24))
.textColor(Color.WHITE)
.bold()
.endConfig()
.buildRound(String.valueOf(unreadCount), getResources().getColor(R.color.green_A700)));
unreadIndicator.setVisibility(View.VISIBLE);
}
}
else
{
unreadIndicator.setVisibility(View.GONE);
if (state == DcMsg.DC_STATE_OUT_ERROR) {
deliveryStatusIndicator.setFailed();
} else if (state == DcMsg.DC_STATE_OUT_MDN_RCVD) {
deliveryStatusIndicator.setRead();
} else if (state == DcMsg.DC_STATE_OUT_DELIVERED) {
deliveryStatusIndicator.setSent();
} else if (state == DcMsg.DC_STATE_OUT_PREPARING) {
deliveryStatusIndicator.setPreparing();
} else if (state == DcMsg.DC_STATE_OUT_PENDING) {
deliveryStatusIndicator.setPending();
} else {
deliveryStatusIndicator.setNone();
}
if (state == DcMsg.DC_STATE_OUT_ERROR) {
deliveryStatusIndicator.setTint(Color.RED);
} else {
deliveryStatusIndicator.resetTint();
}
if(unreadCount==0) {
unreadIndicator.setVisibility(View.GONE);
} else {
unreadIndicator.setImageDrawable(TextDrawable.builder()
.beginConfig()
.width(ViewUtil.dpToPx(getContext(), 24))
.height(ViewUtil.dpToPx(getContext(), 24))
.textColor(Color.WHITE)
.bold()
.endConfig()
.buildRound(String.valueOf(unreadCount), getResources().getColor(R.color.unread_count)));
unreadIndicator.setVisibility(View.VISIBLE);
}
if (state == DcMsg.DC_STATE_OUT_ERROR) {
deliveryStatusIndicator.setFailed();
} else if (state == DcMsg.DC_STATE_OUT_MDN_RCVD) {
deliveryStatusIndicator.setRead();
} else if (state == DcMsg.DC_STATE_OUT_DELIVERED) {
deliveryStatusIndicator.setSent();
} else if (state == DcMsg.DC_STATE_OUT_PREPARING) {
deliveryStatusIndicator.setPreparing();
} else if (state == DcMsg.DC_STATE_OUT_PENDING) {
deliveryStatusIndicator.setPending();
} else {
deliveryStatusIndicator.setNone();
}
if (state == DcMsg.DC_STATE_OUT_ERROR) {
deliveryStatusIndicator.setTint(Color.RED);
} else {
deliveryStatusIndicator.resetTint();
}
}
}
@@ -69,6 +69,17 @@ public class ConversationTitleView extends RelativeLayout {
title.setText(dcChat.getName());
String subtitleStr = "ErrSubtitle";
// set icons etc.
int imgLeft = 0;
int imgRight = 0;
if (dcChat.isMuted()) {
imgLeft = R.drawable.ic_volume_off_white_18dp;
}
if (dcChat.isProtected()) {
imgRight = R.drawable.ic_verified;
}
int[] chatContacts = dcContext.getChatContacts(chatId);
if (dcChat.isMailingList()) {
subtitleStr = context.getString(R.string.mailing_list);
@@ -84,23 +95,16 @@ public class ConversationTitleView extends RelativeLayout {
subtitleStr = context.getString(R.string.device_talk_subtitle);
}
else {
subtitleStr = dcContext.getContact(chatContacts[0]).getAddr();
DcContact dcContact = dcContext.getContact(chatContacts[0]);
subtitleStr = dcContact.getAddr();
if (dcContact.isVerified()) {
imgRight = R.drawable.ic_verified;
}
}
}
subtitle.setText(subtitleStr);
// set icons etc.
int imgLeft = 0;
int imgRight = 0;
if (dcChat.isMuted()) {
imgLeft = R.drawable.ic_volume_off_white_18dp;
}
if (dcChat.isProtected()) {
imgRight = R.drawable.ic_verified;
}
avatar.setAvatar(glideRequests, new Recipient(getContext(), dcChat), false);
title.setCompoundDrawablesWithIntrinsicBounds(imgLeft, 0, imgRight, 0);
subtitle.setVisibility(showAddInfo? View.VISIBLE : View.GONE);
@@ -19,6 +19,7 @@ import com.b44t.messenger.DcLot;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration.StickyHeaderAdapter;
import java.util.ArrayList;
@@ -235,11 +236,12 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
txt = context.getString(R.string.profile_shared_chats);
break;
case ItemData.TYPE_PRIMARY_SETTING:
if(itemDataContact!=null && itemDataContact.isVerified()) {
txt = context.getString(R.string.verified_contact);
long lastSeen = (itemDataContact!=null? itemDataContact.getLastSeen() : 0);
if (lastSeen == 0) {
txt = context.getString(R.string.last_seen_unknown);
}
else {
txt = context.getString(R.string.contact);
txt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, locale, lastSeen));
}
break;
case ItemData.TYPE_STATUS:
@@ -56,6 +56,7 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
private boolean manualConfigure = true; // false: configure by QR account creation
private ProgressDialog progressDialog = null;
private boolean imexUserAborted;
DcContext dcContext;
private NotificationController notificationController;
@@ -164,11 +165,13 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
progressDialog = null;
}
imexUserAborted = false;
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(getResources().getString(R.string.one_moment));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(android.R.string.cancel), (dialog, which) -> {
imexUserAborted = true;
dcContext.stopOngoingProcess();
notificationController.close();
cleanupTempBackupFile();
@@ -222,9 +225,7 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
DcHelper.getEventCenter(this).captureNextError();
if (!dcContext.setConfigFromQr(qrCode)) {
Util.sleep(100); // hack to avoid a race condition, see https://github.com/deltachat/deltachat-core-rust/issues/2787 for more details and possible fix
String err = DcHelper.getEventCenter(this).getCapturedError();
progressError(TextUtils.isEmpty(err) ? "Cannot create account from QR code." : err);
progressError(dcContext.getLastError());
return;
}
@@ -281,7 +282,9 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
if (eventId== DcContext.DC_EVENT_IMEX_PROGRESS ) {
long progress = event.getData1Int();
if (progress==0/*error/aborted*/) {
progressError(DcHelper.getEventCenter(this).getCapturedError());
if (!imexUserAborted) {
progressError(dcContext.getLastError());
}
notificationController.close();
cleanupTempBackupFile();
}
@@ -102,7 +102,7 @@ public class AccountSelectionListItem extends LinearLayout {
.textColor(Color.WHITE)
.bold()
.endConfig()
.buildRound(String.valueOf(unreadCount), getResources().getColor(R.color.green_A700)));
.buildRound(String.valueOf(unreadCount), getResources().getColor(R.color.unread_count)));
unreadIndicator.setVisibility(View.VISIBLE);
}
}
@@ -95,25 +95,11 @@ public class DcEventCenter {
}
private final Object lastErrorLock = new Object();
private String lastErrorString = "";
private boolean showNextErrorAsToast = true;
public void captureNextError() {
synchronized (lastErrorLock) {
showNextErrorAsToast = false;
lastErrorString = "";
}
}
public boolean hasCapturedError() {
synchronized (lastErrorLock) {
return !lastErrorString.isEmpty();
}
}
public String getCapturedError() {
synchronized (lastErrorLock) {
return lastErrorString;
}
}
@@ -128,7 +114,6 @@ public class DcEventCenter {
boolean showAsToast;
Log.e("DeltaChat", string);
synchronized (lastErrorLock) {
lastErrorString = string;
showAsToast = showNextErrorAsToast;
showNextErrorAsToast = true;
}
@@ -18,14 +18,12 @@ import androidx.core.content.FileProvider;
import com.b44t.messenger.DcAccounts;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcLot;
import com.b44t.messenger.DcMsg;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.ConversationActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.notifications.NotificationCenter;
@@ -133,7 +131,6 @@ public class DcHelper {
dcContext.setStockTranslation(11, context.getString(R.string.audio));
dcContext.setStockTranslation(12, context.getString(R.string.file));
dcContext.setStockTranslation(13, context.getString(R.string.pref_default_status_text));
dcContext.setStockTranslation(14, context.getString(R.string.group_hello_draft));
dcContext.setStockTranslation(15, context.getString(R.string.systemmsg_group_name_changed));
dcContext.setStockTranslation(16, context.getString(R.string.systemmsg_group_image_changed));
dcContext.setStockTranslation(17, context.getString(R.string.systemmsg_member_added));
@@ -202,6 +199,8 @@ public class DcHelper {
dcContext.setStockTranslation(116, context.getString(R.string.part_of_total_used));
dcContext.setStockTranslation(117, context.getString(R.string.secure_join_started));
dcContext.setStockTranslation(118, context.getString(R.string.secure_join_replies));
dcContext.setStockTranslation(119, context.getString(R.string.qrshow_join_contact_hint));
dcContext.setStockTranslation(120, context.getString(R.string.qrshow_join_group_hint));
}
public static File getImexDir() {
@@ -32,6 +32,8 @@ public class GeneratedContactPhoto implements FallbackContactPhoto {
.width(targetSize)
.height(targetSize)
.textColor(Color.WHITE)
.bold()
.toUpperCase()
.endConfig()
.buildRound(getCharacter(name), color);
}
@@ -101,8 +101,10 @@ public abstract class ListSummaryPreferenceFragment extends CorrectedPreferenceF
protected ProgressDialog progressDialog = null;
protected int progressWhat = 0;
protected String imexDir = "";
protected boolean imexUserAborted = false;
protected void startImex(int what)
{
imexUserAborted = false;
notificationController = GenericForegroundService.startForegroundTask(getContext(), getString(R.string.export_backup_desktop));
if( progressDialog!=null ) {
progressDialog.dismiss();
@@ -114,6 +116,7 @@ public abstract class ListSummaryPreferenceFragment extends CorrectedPreferenceF
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getActivity().getString(android.R.string.cancel), (dialog, which) -> {
imexUserAborted = true;
dcContext.stopOngoingProcess();
notificationController.close();
notificationController = null;
@@ -136,9 +139,9 @@ public abstract class ListSummaryPreferenceFragment extends CorrectedPreferenceF
DcHelper.getAccounts(context).startIo();
progressDialog.dismiss();
progressDialog = null;
if (DcHelper.getEventCenter(context).hasCapturedError()) {
if (!imexUserAborted) {
new AlertDialog.Builder(context)
.setMessage(DcHelper.getEventCenter(context).getCapturedError())
.setMessage(dcContext.getLastError())
.setPositiveButton(android.R.string.ok, null)
.show();
}
@@ -205,16 +205,15 @@ public class QrCodeHandler {
builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
DcHelper.getEventCenter(activity).captureNextError();
int newChatId = dcContext.joinSecurejoin(qrRawString);
String errorString = DcHelper.getEventCenter(activity).getCapturedError();
DcHelper.getEventCenter(activity).endCaptureNextError();
if (newChatId != 0) {
Intent intent = new Intent(activity, ConversationActivity.class);
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, newChatId);
activity.startActivity(intent);
} else if (!errorString.isEmpty()) {
} else {
AlertDialog.Builder builder1 = new AlertDialog.Builder(activity);
builder1.setMessage(errorString);
builder1.setMessage(dcContext.getLastError());
builder1.setPositiveButton(android.R.string.ok, null);
builder1.create().show();
}
@@ -1,24 +1,16 @@
package org.thoughtcrime.securesms.qr;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -26,10 +18,10 @@ import androidx.fragment.app.Fragment;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.caverock.androidsvg.SVGImageView;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -57,16 +49,6 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
private DcContext dcContext;
private String hint;
private String errorHint;
private TextView hintBelowQr;
private BroadcastReceiver broadcastReceiver;
private Bitmap bitmap;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
@@ -86,43 +68,22 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
chatId = extras.getInt(CHAT_ID);
}
errorHint = getString(R.string.qrshow_join_contact_no_connection_hint);
if (chatId != 0) {
// verified-group
String groupName = dcContext.getChat(chatId).getName();
hint = String.format(this.getString(R.string.qrshow_join_group_hint), groupName);
} else {
// verify-contact
String selfName = DcHelper.get(getActivity(), DcHelper.CONFIG_DISPLAY_NAME); // we cannot use MrContact.getDisplayName() as this would result in "Me" instead of
String nameAndAddress;
if (selfName.isEmpty()) {
selfName = DcHelper.get(getActivity(), DcHelper.CONFIG_ADDRESS, "unknown");
nameAndAddress = selfName;
} else {
nameAndAddress = String.format("%s (%s)", selfName, DcHelper.get(getActivity(), DcHelper.CONFIG_ADDRESS));
}
hint = String.format(this.getString(R.string.qrshow_join_contact_hint), nameAndAddress);
}
hintBelowQr = view.findViewById(R.id.qrShowHint);
setHintText();
dcEventCenter.addObserver(DcContext.DC_EVENT_SECUREJOIN_INVITER_PROGRESS, this);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setHintText();
}
};
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
numJoiners = 0;
ImageView imageView = view.findViewById(R.id.qrImage);
SVGImageView imageView = view.findViewById(R.id.qrImage);
try {
bitmap = encodeAsBitmap(dcContext.getSecurejoinQr(chatId));
imageView.setImageBitmap(bitmap);
} catch (WriterException e) {
String svg_txt = dcContext.getSecurejoinQrSvg(chatId);
// HACK: move avatar-letter down, baseline alignment not working,
// see https://github.com/deltachat/deltachat-core-rust/pull/2815#issuecomment-978067378 ,
// suggestions welcome :)
svg_txt = svg_txt.replace("y=\"281.136\"", "y=\"290\"");
SVG svg = SVG.getFromString(svg_txt);
imageView.setSVG(svg);
} catch (SVGParseException e) {
e.printStackTrace();
}
@@ -135,6 +96,11 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
file.createNewFile();
file.setReadable(true, false);
FileOutputStream stream = new FileOutputStream(file);
Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawRGB(255, 255, 255); // Clear background to white
SVG svg = SVG.getFromString(dcContext.getSecurejoinQrSvg(chatId));
svg.renderToCanvas(canvas);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
stream.flush();
stream.close();
@@ -142,7 +108,6 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TEXT, hint);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, getString(R.string.chat_share_with_title)));
} catch (Exception e) {
@@ -155,14 +120,6 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
Toast.makeText(getActivity(), getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show();
}
private void setHintText() {
if (!DcHelper.isNetworkConnected(getContext())) {
hintBelowQr.setText(errorHint);
} else {
hintBelowQr.setText(hint);
}
}
@Override
public void onResume() {
super.onResume();
@@ -175,47 +132,6 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel
public void onDestroyView() {
super.onDestroyView();
dcEventCenter.removeObservers(this);
getActivity().unregisterReceiver(broadcastReceiver);
}
private Bitmap encodeAsBitmap(String str) throws WriterException {
BitMatrix result;
try {
result = new MultiFormatWriter().encode(str,
BarcodeFormat.QR_CODE, WIDTH, HEIGHT, null);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
Bitmap overlay = BitmapFactory.decodeResource(this.getResources(), R.drawable.qr_overlay);
putOverlay(bitmap, overlay);
return bitmap;
}
private void putOverlay(Bitmap bitmap, Bitmap overlay) {
int bw = bitmap.getWidth();
int bh = bitmap.getHeight();
int ow = bw / 6;
int oh = bh / 6;
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(overlay, null, new Rect(bw / 2 - ow / 2, bh / 2 - oh / 2, bw / 2 + ow / 2, bh / 2 + oh / 2), paint);
}
@Override
@@ -77,6 +77,19 @@ public class DateUtils extends android.text.format.DateUtils {
}
}
public static String getExtendedTimeSpanString(final Context c, final Locale locale, final long timestamp) {
StringBuilder format = new StringBuilder();
if (DateUtils.isToday(timestamp)) {}
else if (isWithin(timestamp, 6, TimeUnit.DAYS)) format.append("EEE ");
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format.append("MMM d, ");
else format.append("MMM d, yyyy, ");
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
else format.append("hh:mm a");
return getFormattedDateTime(timestamp, format.toString(), locale);
}
public static String getExtendedRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
return c.getString(R.string.now);
@@ -84,16 +97,7 @@ public class DateUtils extends android.text.format.DateUtils {
int mins = (int)TimeUnit.MINUTES.convert(System.currentTimeMillis() - timestamp, TimeUnit.MILLISECONDS);
return c.getResources().getQuantityString(R.plurals.n_minutes, mins, mins);
} else {
StringBuilder format = new StringBuilder();
if (DateUtils.isToday(timestamp)) {}
else if (isWithin(timestamp, 6, TimeUnit.DAYS)) format.append("EEE ");
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format.append("MMM d, ");
else format.append("MMM d, yyyy, ");
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
else format.append("hh:mm a");
return getFormattedDateTime(timestamp, format.toString(), locale);
return getExtendedTimeSpanString(c, locale, timestamp);
}
}