Allow login with qr & Refine its scan
This commit is contained in:
parent
b36ec33936
commit
0072eaaab0
@ -1,8 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
def verName = "7.2.1"
|
||||
def verCode = 117
|
||||
def verName = "7.2.1.1"
|
||||
def verCode = 118
|
||||
|
||||
def serviceAccountCredentialsFile = rootProject.file("service_account_credentials.json")
|
||||
|
||||
|
@ -195,6 +195,12 @@ void setLayer(JNIEnv *env, jclass c, jint instanceNum, jint layer) {
|
||||
|
||||
}
|
||||
|
||||
void moveToDatacenter(JNIEnv *env, jclass c, jint instanceNum, jint datacenterId) {
|
||||
|
||||
ConnectionsManager::getInstance(instanceNum).moveToDatacenter((uint32_t) datacenterId);
|
||||
|
||||
}
|
||||
|
||||
void saveDatacenters(JNIEnv *env, jclass c,jint instanceNum) {
|
||||
|
||||
ConnectionsManager::getInstance(instanceNum).saveDatacenters();
|
||||
@ -478,6 +484,7 @@ static JNINativeMethod ConnectionsManagerMethods[] = {
|
||||
{"native_setDatacenterAddress", "(IILjava/lang/String;Ljava/lang/String;I)V", (void *) setDatacenterAddress},
|
||||
{"native_saveDatacenters", "(I)V", (void *) saveDatacenters},
|
||||
{"native_setLayer", "(II)V", (void *) setLayer},
|
||||
{"native_moveToDatacenter", "(II)V", (void *) moveToDatacenter},
|
||||
{"native_setProxySettings", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", (void *) setProxySettings},
|
||||
{"native_getConnectionState", "(I)I", (void *) getConnectionState},
|
||||
{"native_setUserId", "(II)V", (void *) setUserId},
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
void setPushConnectionEnabled(bool value);
|
||||
void applyDnsConfig(NativeByteBuffer *buffer, std::string phone, int32_t date);
|
||||
void setMtProtoVersion(int version);
|
||||
void moveToDatacenter(uint32_t datacenterId);
|
||||
|
||||
int32_t getMtProtoVersion();
|
||||
int64_t checkProxy(std::string address, uint16_t port, std::string username, std::string password, std::string secret, onRequestTimeFunc requestTimeFunc, jobject ptr1);
|
||||
|
||||
@ -101,7 +103,6 @@ private:
|
||||
void clearRequestsForDatacenter(Datacenter *datacenter, HandshakeType type);
|
||||
void registerForInternalPushUpdates();
|
||||
void processRequestQueue(uint32_t connectionType, uint32_t datacenterId);
|
||||
void moveToDatacenter(uint32_t datacenterId);
|
||||
void authorizeOnMovingDatacenter();
|
||||
void authorizedOnMovingDatacenter();
|
||||
Datacenter *getDatacenterWithId(uint32_t datacenterId);
|
||||
|
@ -2189,7 +2189,7 @@ Telegram 团队</string>
|
||||
<string name="ConvertGroupAlert">此操作是不可逆的。超级群组不可能降级为普通群组。</string>
|
||||
<string name="EventLogDeletedMessages">un1 删除了这条消息:</string>
|
||||
<string name="KMetersAway">千米以外</string>
|
||||
<string name="AuthAnotherClient">通过二维码登录</string>
|
||||
<string name="QRLoginConfirm">通过二维码登录</string>
|
||||
<string name="VideoMessagesAutodownload">视频消息</string>
|
||||
<string name="NotificationMessageStickerEmoji">%1$s 给您发送了一个 %2$s 表情</string>
|
||||
<string name="StickersArchivedInfo">%1$s 已移动到您的归档中。</string>
|
||||
|
@ -16,7 +16,7 @@ import android.content.pm.PackageManager;
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class BuildVars {
|
||||
|
||||
public static boolean DEBUG_VERSION = BuildConfig.BUILD_TYPE.equals("debug") || BuildConfig.VERSION_NAME.contains("preview");
|
||||
public static boolean DEBUG_VERSION = BuildConfig.BUILD_TYPE.equals("debug");
|
||||
public static boolean DEBUG_PRIVATE_VERSION = DEBUG_VERSION;
|
||||
public static boolean LOGS_ENABLED;
|
||||
public static boolean USE_CLOUD_STRINGS = true;
|
||||
|
@ -12144,6 +12144,11 @@ public class MessagesController extends BaseController implements NotificationCe
|
||||
updatesOnMainThread = new ArrayList<>();
|
||||
}
|
||||
updatesOnMainThread.add(baseUpdate);
|
||||
} else if (baseUpdate instanceof TLRPC.TL_updateLoginToken) {
|
||||
if (updatesOnMainThread == null) {
|
||||
updatesOnMainThread = new ArrayList<>();
|
||||
}
|
||||
updatesOnMainThread.add(baseUpdate);
|
||||
}
|
||||
}
|
||||
if (messages != null) {
|
||||
@ -12688,6 +12693,8 @@ public class MessagesController extends BaseController implements NotificationCe
|
||||
} else if (baseUpdate instanceof TLRPC.TL_updateReadChannelDiscussionOutbox) {
|
||||
TLRPC.TL_updateReadChannelDiscussionOutbox update = (TLRPC.TL_updateReadChannelDiscussionOutbox) baseUpdate;
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.threadMessagesRead, (long) -update.channel_id, update.top_msg_id, 0, update.read_max_id);
|
||||
} else if (baseUpdate instanceof TLRPC.TL_updateLoginToken) {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.updateLoginToken);
|
||||
}
|
||||
}
|
||||
if (editor != null) {
|
||||
|
@ -204,6 +204,8 @@ public class NotificationCenter {
|
||||
// custom
|
||||
|
||||
public static final int updateUserStatus = totalEvents++;
|
||||
public static final int updateLoginToken = totalEvents++;
|
||||
|
||||
|
||||
private SparseArray<ArrayList<NotificationCenterDelegate>> observers = new SparseArray<>();
|
||||
private SparseArray<ArrayList<NotificationCenterDelegate>> removeAfterBroadcast = new SparseArray<>();
|
||||
|
@ -690,6 +690,8 @@ public class ConnectionsManager extends BaseController {
|
||||
|
||||
public static native void native_setLayer(int currentAccount, int layer);
|
||||
|
||||
public static native void native_moveToDatacenter(int currentAccount, int datacenterId);
|
||||
|
||||
public static native int native_getConnectionState(int currentAccount);
|
||||
|
||||
public static native void native_setUserId(int currentAccount, int id);
|
||||
|
@ -1137,7 +1137,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
|
||||
}
|
||||
|
||||
public Builder setMessage(CharSequence message) {
|
||||
alertDialog.message = message;
|
||||
alertDialog.message = message instanceof String ? AndroidUtilities.replaceTags((String) message) : message;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ImageFormat;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Point;
|
||||
@ -25,7 +24,6 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
@ -35,14 +33,15 @@ import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.PlanarYUVLuminanceSource;
|
||||
import com.google.zxing.RGBLuminanceSource;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.qrcode.QRCodeReader;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLoader;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
@ -63,7 +62,6 @@ import org.telegram.ui.Components.AnimationProperties;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@TargetApi(18)
|
||||
@ -89,7 +87,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
|
||||
//private BarcodeDetector visionQrReader;
|
||||
|
||||
private boolean needGalleryButton;
|
||||
private boolean any;
|
||||
private boolean any;
|
||||
|
||||
private int currentType;
|
||||
|
||||
@ -664,21 +662,27 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
|
||||
text = null;
|
||||
}
|
||||
} else {*/
|
||||
LuminanceSource source;
|
||||
if (bitmap != null) {
|
||||
int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()];
|
||||
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray);
|
||||
} else {
|
||||
source = new PlanarYUVLuminanceSource(data, size.getWidth(), size.getHeight(), x, y, side, side, false);
|
||||
}
|
||||
|
||||
Result result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
|
||||
if (result == null) {
|
||||
onNoQrFound();
|
||||
return null;
|
||||
}
|
||||
text = result.getText();
|
||||
LuminanceSource source;
|
||||
if (bitmap != null) {
|
||||
int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()];
|
||||
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray);
|
||||
} else {
|
||||
source = new PlanarYUVLuminanceSource(data, size.getWidth(), size.getHeight(), x, y, side, side, false);
|
||||
}
|
||||
Result result = null;
|
||||
try {
|
||||
result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
|
||||
} catch (NotFoundException e) {
|
||||
try {
|
||||
result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source.invert())));
|
||||
} catch (NotFoundException ignore) {}
|
||||
}
|
||||
if (result == null) {
|
||||
onNoQrFound();
|
||||
return null;
|
||||
}
|
||||
text = result.getText();
|
||||
//}
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
onNoQrFound();
|
||||
@ -692,11 +696,6 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
|
||||
}
|
||||
Uri uri = Uri.parse(text);
|
||||
String path = uri.getPath().replace("/", "");
|
||||
} else {
|
||||
if (!text.startsWith("tg://login?token=")) {
|
||||
onNoQrFound();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
} catch (Throwable ignore) {
|
||||
|
@ -32,6 +32,7 @@ import android.os.Parcelable;
|
||||
import android.os.StatFs;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.ContactsContract;
|
||||
import android.se.omapi.Session;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.view.ActionMode;
|
||||
@ -119,6 +120,7 @@ import org.telegram.ui.Components.StickersAlert;
|
||||
import org.telegram.ui.Components.Switch;
|
||||
import org.telegram.ui.Components.TermsOfServiceView;
|
||||
import org.telegram.ui.Components.ThemeEditorView;
|
||||
import org.telegram.ui.Components.UndoView;
|
||||
import org.telegram.ui.Components.voip.VoIPHelper;
|
||||
|
||||
import java.io.File;
|
||||
@ -129,7 +131,9 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlin.text.StringsKt;
|
||||
import tw.nekomimi.nekogram.BottomBuilder;
|
||||
import tw.nekomimi.nekogram.ExternalGcm;
|
||||
import tw.nekomimi.nekogram.NekoConfig;
|
||||
import tw.nekomimi.nekogram.NekoXConfig;
|
||||
@ -2472,11 +2476,47 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||
}
|
||||
return;
|
||||
} else if (loginToken != null) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(LaunchActivity.this);
|
||||
builder.setTitle(LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient));
|
||||
builder.setMessage(LocaleController.getString("AuthAnotherClientUrl", R.string.AuthAnotherClientUrl));
|
||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
|
||||
showAlertDialog(builder);
|
||||
BottomBuilder builder = new BottomBuilder(this);
|
||||
builder.addTitle(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan), LocaleController.getString("QRLoginNotice",R.string.QRLoginNotice));
|
||||
builder.addItem(LocaleController.getString("QRLoginConfirm", R.string.QRLoginConfirm), R.drawable.baseline_security_24, true, (c) -> {
|
||||
AlertDialog progressDialog = new AlertDialog(this, 3);
|
||||
progressDialog.setCanCacnel(false);
|
||||
progressDialog.show();
|
||||
byte[] token = Base64.decode(loginToken, Base64.URL_SAFE);
|
||||
TLRPC.TL_auth_acceptLoginToken req = new TLRPC.TL_auth_acceptLoginToken();
|
||||
req.token = token;
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
if (response instanceof TLRPC.TL_authorization) {
|
||||
SessionsActivity fragment = new SessionsActivity(0);
|
||||
fragment.newAuthorizationToOpen = (TLRPC.TL_authorization) response;
|
||||
presentFragment(fragment, false, false);
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
actionBarLayout.showLastFragment();
|
||||
rightActionBarLayout.showLastFragment();
|
||||
drawerLayoutContainer.setAllowOpenDrawer(false, false);
|
||||
} else {
|
||||
drawerLayoutContainer.setAllowOpenDrawer(true, false);
|
||||
}
|
||||
} else {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
final String text;
|
||||
if (error.text.equals("AUTH_TOKEN_EXCEPTION")) {
|
||||
text = LocaleController.getString("AccountAlreadyLoggedIn", R.string.AccountAlreadyLoggedIn);
|
||||
} else {
|
||||
text = LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text;
|
||||
}
|
||||
AlertUtil.showSimpleAlert(this, LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), text);
|
||||
});
|
||||
}
|
||||
}));
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
builder.addCancelItem();
|
||||
builder.show();
|
||||
return;
|
||||
}
|
||||
final AlertDialog progressDialog = new AlertDialog(this, 3);
|
||||
|
@ -135,6 +135,7 @@ import tw.nekomimi.nekogram.EditTextAutoFill;
|
||||
import tw.nekomimi.nekogram.NekoXConfig;
|
||||
import tw.nekomimi.nekogram.parts.PKCS1Pub;
|
||||
import tw.nekomimi.nekogram.utils.AlertUtil;
|
||||
import tw.nekomimi.nekogram.utils.ProxyUtil;
|
||||
import tw.nekomimi.nekogram.utils.VibrateUtil;
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
@ -277,6 +278,11 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
|
||||
private int menu_other = 5;
|
||||
private int menu_custom_api = 6;
|
||||
private int menu_custom_dc = 7;
|
||||
private int menu_qr_login = 8;
|
||||
|
||||
TLRPC.TL_auth_exportLoginToken exportLoginTokenRequest = null;
|
||||
AlertDialog exportLoginTokenProgress = null;
|
||||
android.app.AlertDialog exportLoginTokenDialog = null;
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
@ -899,6 +905,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
|
||||
});
|
||||
|
||||
builder.show();
|
||||
} else if (id == menu_qr_login) {
|
||||
regenerateLoginToken(false);
|
||||
}
|
||||
|
||||
}
|
||||
@ -922,6 +930,7 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
|
||||
Locale current = ConfigurationCompat.getLocales(getParentActivity().getResources().getConfiguration()).get(0);
|
||||
|
||||
otherItem.addSubItem(4, R.drawable.list_bot, LocaleController.getString("BotLogin", R.string.BotLogin));
|
||||
otherItem.addSubItem(menu_qr_login, R.drawable.wallet_qr, LocaleController.getString("ImportLogin", R.string.ImportLogin));
|
||||
otherItem.addSubItem(menu_custom_api, R.drawable.baseline_vpn_key_24, LocaleController.getString("CustomApi", R.string.CustomApi));
|
||||
otherItem.addSubItem(menu_custom_dc, R.drawable.baseline_sync_24, LocaleController.getString("CustomBackend", R.string.CustomBackend));
|
||||
|
||||
@ -1080,6 +1089,128 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
private void regenerateLoginToken(Boolean refresh) {
|
||||
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken);
|
||||
|
||||
if (getParentActivity() == null || isFinished) return;
|
||||
|
||||
if (exportLoginTokenDialog != null && exportLoginTokenDialog.isShowing()) {
|
||||
exportLoginTokenDialog.dismiss();
|
||||
} else if (refresh) return;
|
||||
|
||||
exportLoginTokenProgress = new AlertDialog(getParentActivity(), 3);
|
||||
exportLoginTokenProgress.setCanCacnel(false);
|
||||
exportLoginTokenProgress.show();
|
||||
|
||||
if (exportLoginTokenRequest == null) {
|
||||
exportLoginTokenRequest = new TLRPC.TL_auth_exportLoginToken();
|
||||
exportLoginTokenRequest.api_id = NekoXConfig.currentAppId();
|
||||
exportLoginTokenRequest.api_hash = NekoXConfig.currentAppHash();
|
||||
exportLoginTokenRequest.except_ids = new ArrayList<>();
|
||||
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
|
||||
UserConfig userConfig = UserConfig.getInstance(a);
|
||||
if (!userConfig.isClientActivated()) {
|
||||
continue;
|
||||
}
|
||||
exportLoginTokenRequest.except_ids.add(a);
|
||||
}
|
||||
}
|
||||
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.updateLoginToken);
|
||||
|
||||
getConnectionsManager().sendRequest(exportLoginTokenRequest, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
if (getParentActivity() == null) return;
|
||||
|
||||
try {
|
||||
exportLoginTokenProgress.dismiss();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
if (response instanceof TLRPC.TL_auth_loginToken) {
|
||||
exportLoginTokenDialog = ProxyUtil.showQrDialog(getParentActivity(), "tg://login?token=" + Base64.encodeUrlSafe(((TLRPC.TL_auth_loginToken) response).token));
|
||||
int delay = (int) (((TLRPC.TL_auth_loginToken) response).expires - System.currentTimeMillis() / 1000);
|
||||
if (BuildVars.DEBUG_VERSION) {
|
||||
AlertUtil.showToast("Refresh after " + delay + "s");
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> regenerateLoginToken(true), ((TLRPC.TL_auth_loginToken) response).expires * 1000L - System.currentTimeMillis());
|
||||
} else if (response instanceof TLRPC.TL_auth_loginTokenMigrateTo) {
|
||||
checkMigrateTo((TLRPC.TL_auth_loginTokenMigrateTo) response);
|
||||
} else if (response instanceof TLRPC.TL_auth_loginTokenSuccess) {
|
||||
processLoginByTokenFinish((TLRPC.TL_auth_loginTokenSuccess) response);
|
||||
} else {
|
||||
if (error.text.contains("SESSION_PASSWORD_NEEDED")) {
|
||||
exportLoginTokenProgress.show();
|
||||
TLRPC.TL_account_getPassword req2 = new TLRPC.TL_account_getPassword();
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req2, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
exportLoginTokenProgress.dismiss();
|
||||
showDoneButton(false, true);
|
||||
if (error1 == null) {
|
||||
TLRPC.TL_account_password password = (TLRPC.TL_account_password) response1;
|
||||
if (!TwoStepVerificationActivity.canHandleCurrentPassword(password, true)) {
|
||||
AlertsCreator.showUpdateAppAlert(getParentActivity(), LocaleController.getString("UpdateAppAlert", R.string.UpdateAppAlert), true);
|
||||
return;
|
||||
}
|
||||
Bundle bundle = new Bundle();
|
||||
if (password.current_algo instanceof TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) {
|
||||
TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo = (TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) password.current_algo;
|
||||
bundle.putString("current_salt1", Utilities.bytesToHex(algo.salt1));
|
||||
bundle.putString("current_salt2", Utilities.bytesToHex(algo.salt2));
|
||||
bundle.putString("current_p", Utilities.bytesToHex(algo.p));
|
||||
bundle.putInt("current_g", algo.g);
|
||||
bundle.putString("current_srp_B", Utilities.bytesToHex(password.srp_B));
|
||||
bundle.putLong("current_srp_id", password.srp_id);
|
||||
bundle.putInt("passwordType", 1);
|
||||
}
|
||||
bundle.putString("hint", password.hint != null ? password.hint : "");
|
||||
bundle.putString("email_unconfirmed_pattern", password.email_unconfirmed_pattern != null ? password.email_unconfirmed_pattern : "");
|
||||
bundle.putInt("has_recovery", password.has_recovery ? 1 : 0);
|
||||
setPage(6, true, bundle, false);
|
||||
} else {
|
||||
needShowAlert(LocaleController.getString("NekoX", R.string.NekoX), error1.text);
|
||||
}
|
||||
}), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin);
|
||||
} else {
|
||||
AlertUtil.showToast(error);
|
||||
}
|
||||
}
|
||||
}), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin | ConnectionsManager.RequestFlagTryDifferentDc | ConnectionsManager.RequestFlagEnableUnauthorized);
|
||||
|
||||
}
|
||||
|
||||
private void checkMigrateTo(TLRPC.TL_auth_loginTokenMigrateTo response) {
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken);
|
||||
ConnectionsManager.native_moveToDatacenter(currentAccount, response.dc_id);
|
||||
exportLoginTokenProgress.show();
|
||||
|
||||
TLRPC.TL_auth_importLoginToken request = new TLRPC.TL_auth_importLoginToken();
|
||||
request.token = response.token;
|
||||
getConnectionsManager().sendRequest(request, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
exportLoginTokenProgress.dismiss();
|
||||
if (error1 != null) {
|
||||
exportLoginTokenRequest = null;
|
||||
regenerateLoginToken(false);
|
||||
} else if (response1 instanceof TLRPC.TL_auth_loginTokenSuccess) {
|
||||
processLoginByTokenFinish((TLRPC.TL_auth_loginTokenSuccess) response1);
|
||||
}
|
||||
}), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin | ConnectionsManager.RequestFlagTryDifferentDc | ConnectionsManager.RequestFlagEnableUnauthorized);
|
||||
|
||||
}
|
||||
|
||||
private void processLoginByTokenFinish(TLRPC.TL_auth_loginTokenSuccess authLoginTokenSuccess) {
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken);
|
||||
|
||||
TLRPC.auth_Authorization authorization = authLoginTokenSuccess.authorization;
|
||||
if (authorization instanceof TLRPC.TL_auth_authorizationSignUpRequired) {
|
||||
TLRPC.TL_auth_authorizationSignUpRequired authorizationI = (TLRPC.TL_auth_authorizationSignUpRequired) authorization;
|
||||
if (authorizationI.terms_of_service != null) {
|
||||
currentTermsOfService = authorizationI.terms_of_service;
|
||||
}
|
||||
setPage(5, true, new Bundle(), false);
|
||||
} else {
|
||||
onAuthSuccess((TLRPC.TL_auth_authorization) authorization);
|
||||
}
|
||||
}
|
||||
|
||||
private int currentConnectionState;
|
||||
|
||||
@Override
|
||||
@ -1090,6 +1221,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
|
||||
currentConnectionState = state;
|
||||
updateProxyButton(true);
|
||||
}
|
||||
} else if (id == NotificationCenter.updateLoginToken) {
|
||||
regenerateLoginToken(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,8 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
|
||||
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.newSessionReceived);
|
||||
}
|
||||
|
||||
TLRPC.TL_authorization newAuthorizationToOpen;
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
||||
@ -421,6 +423,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
|
||||
frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8));
|
||||
}
|
||||
|
||||
if (newAuthorizationToOpen != null) {
|
||||
AndroidUtilities.runOnUIThread(() -> undoView.showWithAction(0, UndoView.ACTION_QR_SESSION_ACCEPTED, newAuthorizationToOpen), 3000L);
|
||||
}
|
||||
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ public class NekoConfig {
|
||||
mediaPreview = preferences.getBoolean("mediaPreview", false);
|
||||
|
||||
proxyAutoSwitch = preferences.getBoolean("proxy_auto_switch", false);
|
||||
usePersianCalender = preferences.getBoolean("usePersianCalender", false);
|
||||
usePersianCalender = false;//preferences.getBoolean("usePersianCalender", false);
|
||||
openPGPApp = preferences.getString("openPGPApp","");
|
||||
openPGPKeyId = preferences.getLong("openPGPKeyId",0L);
|
||||
|
||||
|
@ -2,6 +2,7 @@ package tw.nekomimi.nekogram.utils
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
@ -349,13 +350,13 @@ object ProxyUtil {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showQrDialog(ctx: Context, text: String) {
|
||||
fun showQrDialog(ctx: Context, text: String): AlertDialog {
|
||||
|
||||
val code = createQRCode(text)
|
||||
|
||||
ctx.setTheme(R.style.Theme_TMessages)
|
||||
|
||||
android.app.AlertDialog.Builder(ctx).setView(LinearLayout(ctx).apply {
|
||||
return AlertDialog.Builder(ctx).setView(LinearLayout(ctx).apply {
|
||||
|
||||
addView(LinearLayout(ctx).apply {
|
||||
|
||||
@ -461,28 +462,30 @@ object ProxyUtil {
|
||||
@JvmStatic
|
||||
fun tryReadQR(ctx: Activity, bitmap: Bitmap) {
|
||||
|
||||
val intArray = IntArray(bitmap.getWidth() * bitmap.getHeight())
|
||||
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight())
|
||||
val source = RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray)
|
||||
val intArray = IntArray(bitmap.width * bitmap.height)
|
||||
bitmap.getPixels(intArray, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
|
||||
val source = RGBLuminanceSource(bitmap.width, bitmap.height, intArray)
|
||||
|
||||
try {
|
||||
|
||||
val result = qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source)))
|
||||
|
||||
if (result == null || result.text.isBlank()) {
|
||||
|
||||
AlertUtil.showToast(LocaleController.getString("NoQrFound", R.string.NoQrFound))
|
||||
|
||||
} else {
|
||||
|
||||
showLinkAlert(ctx, result.text)
|
||||
|
||||
val result = try {
|
||||
qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source)))
|
||||
} catch (e: NotFoundException) {
|
||||
qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source.invert())))
|
||||
}
|
||||
|
||||
showLinkAlert(ctx, result.text)
|
||||
|
||||
val intArr = arrayListOf<Int>().toIntArray()
|
||||
|
||||
} catch (ex: NoSuchMethodError) {
|
||||
|
||||
AlertUtil.showSimpleAlert(ctx, "很抱歉, 這是一個已知的問題, 但您現在無法掃碼, 因爲您正在使用糟糕的Android系統, 直到 Google Zxing 為您的設備做出優化.")
|
||||
|
||||
} catch (e: Throwable) {
|
||||
|
||||
AlertUtil.showToast(LocaleController.getString("NoQrFound", R.string.NoQrFound))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -495,7 +498,7 @@ object ProxyUtil {
|
||||
var isUrl = false
|
||||
|
||||
runCatching {
|
||||
text.toHttpUrlOrNull()!!
|
||||
text.replace("tg://", "https://t.me/").toHttpUrlOrNull()!!
|
||||
if (Browser.isInternalUrl(text, booleanArrayOf(false))) {
|
||||
Browser.openUrl(ctx, text)
|
||||
return
|
||||
|
@ -252,6 +252,8 @@
|
||||
<string name="UnpinMessageX">Unpin message</string>
|
||||
<string name="UnpinMessagesAll">Unpin all messages</string>
|
||||
<string name="DismissForYourself">Dismiss for yourself</string>
|
||||
|
||||
<string name="ImportLogin">QR Login</string>
|
||||
<string name="QRLoginNotice">This QR code / link allows someone to log in to your Telegram account. Is this your own operation?</string>
|
||||
<string name="QRLoginConfirm">Confirm Login</string>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user