Imps & Add text replacer

This commit is contained in:
世界 2021-02-01 01:28:28 +08:00
parent e3d67c0f7e
commit 3b9f39167f
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
12 changed files with 185 additions and 85 deletions

View File

@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
def verName = "7.4.2-preview-2227"
def verCode = 171
def verName = "7.4.2-preview-5"
def verCode = 172
def serviceAccountCredentialsFile = rootProject.file("service_account_credentials.json")
@ -37,7 +37,7 @@ configurations {
compile.exclude module: 'support-v4'
}
def okHttpVersion = '4.9.0'
def okHttpVersion = '5.0.0-alpha.2'
def fcmVersion = '21.0.1'
def crashlyticsVersion = '17.3.1'
def playCoreVersion = '1.9.1'
@ -73,7 +73,7 @@ dependencies {
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.osmdroid:osmdroid-android:6.1.8'
implementation 'org.osmdroid:osmdroid-android:6.1.10'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.21-2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

View File

@ -43,7 +43,11 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import kotlin.collections.ArraysKt;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.parts.LocFiltersKt;
import tw.nekomimi.nekogram.utils.FileUtil;
public class LocaleController {
@ -1024,6 +1028,8 @@ public class LocaleController {
}
if (value == null) {
value = "LOC_ERR:" + key;
} else {
value = LocFiltersKt.filter(value);
}
return value;
}

View File

@ -279,10 +279,11 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter imple
int savedIcon = R.drawable.baseline_bookmark_24;
int settingsIcon = R.drawable.baseline_settings_24;
int inviteIcon = R.drawable.baseline_person_add_24;
int callsIcon = R.drawable.baseline_call_24;
items.add(new Item(6, LocaleController.getString("Contacts", R.string.Contacts), contactsIcon));
items.add(new Item(11, LocaleController.getString("SavedMessages", R.string.SavedMessages), savedIcon));
items.add(new Item(8, LocaleController.getString("Settings", R.string.Settings), settingsIcon));
items.add(new Item(7, LocaleController.getString("InviteFriends", R.string.InviteFriends), inviteIcon));
items.add(new Item(10, LocaleController.getString("Calls", R.string.Calls), callsIcon));
if (NekoConfig.useProxyItem && (!NekoConfig.hideProxyByDefault || SharedConfig.proxyEnabled)) {
items.add(new CheckItem(13, LocaleController.getString("Proxy", R.string.Proxy), R.drawable.baseline_security_24, () -> SharedConfig.proxyEnabled, () -> {
SharedConfig.setProxyEnable(!SharedConfig.proxyEnabled);

View File

@ -1979,6 +1979,9 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
String plainText = ((TLRPC.TL_textPlain) richText).text;
if (!noTranslate && StrUtil.isNotBlank(plainText) && adapter[0].trans && TranslateDb.currentTarget().contains(plainText)) {
plainText = TranslateDb.currentTarget().query(plainText);
if (plainText == null) {
plainText = ((TLRPC.TL_textPlain) richText).text + " (Not translated)";
}
}
return plainText;
} else if (richText instanceof TLRPC.TL_textAnchor) {

View File

@ -282,7 +282,7 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
ActionBarMenu menu = actionBar.createMenu();
otherItem = menu.addItem(10, R.drawable.ic_ab_other);
otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
otherItem.addSubItem(delete_all_calls, R.drawable.msg_delete, LocaleController.getString("DeleteAllCalls", R.string.DeleteAllCalls));
otherItem.addSubItem(delete_all_calls, R.drawable.baseline_delete_sweep_24, LocaleController.getString("DeleteAllCalls", R.string.DeleteAllCalls));
fragmentView = new FrameLayout(context);
fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));

View File

@ -45,8 +45,8 @@ public class TextCheckCell extends FrameLayout {
private TextView textView;
private TextView valueTextView;
private Switch checkBox;
private CheckBoxSquare checkBoxSquare;
public Switch checkBox;
public CheckBoxSquare checkBoxSquare;
private boolean needDivider;
private boolean isMultiline;
private int height = 50;

View File

@ -70,6 +70,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -121,6 +122,7 @@ import org.telegram.ui.ActionBar.AdjustPanLayoutHelper;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextCheckCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.GroupStickersActivity;
@ -137,9 +139,11 @@ import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import kotlin.text.StringsKt;
import tw.nekomimi.nekogram.BottomBuilder;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.cc.CCConverter;
import tw.nekomimi.nekogram.cc.CCTarget;
@ -2330,17 +2334,17 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if (!hasRecordVideo || calledRecordRunnable) {
startedDraggingX = -1;
if (hasRecordVideo && videoSendButton.getTag() != null) {
delegate.needStartRecordVideo(1, true, 0);
} else {
if (recordingAudioVideo && isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0));
}
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0);
delegate.needStartRecordVideo(1, true, 0);
} else {
if (recordingAudioVideo && isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0));
}
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0);
delegate.needStartRecordAudio(0);
}
recordingAudioVideo = false;
updateRecordIntefrace(RECORD_STATE_SENDING);
}
recordingAudioVideo = false;
updateRecordIntefrace(RECORD_STATE_SENDING);
}
return false;
}
if (parentFragment != null) {
@ -3045,8 +3049,19 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
});
cell.setMinimumWidth(AndroidUtilities.dp(196));
menuPopupLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 0, 48 * a++, 0, 0));
cell = new ActionBarMenuSubItem(getContext(), false, dlps == 0);
cell.setTextAndIcon(LocaleController.getString("ReplaceText", R.string.ReplaceText), R.drawable.baseline_edit_24);
cell.setOnClickListener(v -> {
if (menuPopupWindow != null && menuPopupWindow.isShowing()) {
menuPopupWindow.dismiss();
}
showReplace();
});
cell.setMinimumWidth(AndroidUtilities.dp(196));
menuPopupLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 0, 48 * a++, 0, 0));
}
if (dlps > 0) {
@ -3315,13 +3330,21 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
private void translateComment(Locale target) {
int start = messageEditText.getSelectionStart();
int end = messageEditText.getSelectionEnd();
CharSequence text = messageEditText.getText();
if (start != end) {
text = text.subSequence(start, end);
}
TranslateDb db = TranslateDb.forLocale(target);
String origin = messageEditText.getText().toString();
String origin = text.toString();
if (db.contains(origin)) {
String translated = db.query(origin);
messageEditText.setText(translated);
if (start == end) messageEditText.setText(translated);
else messageEditText.getText().replace(start, end, translated);
return;
@ -3345,7 +3368,8 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
@Override
public void onSuccess(@NotNull String translation) {
status.dismiss();
messageEditText.setText(translation);
if (start == end) messageEditText.setText(translation);
else messageEditText.getText().replace(start, end, translation);
}
@Override
@ -3363,18 +3387,78 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
private void ccComment(String target) {
String text = messageEditText.getText().toString();
int start = messageEditText.getSelectionStart();
int end = messageEditText.getSelectionEnd();
CharSequence text = messageEditText.getText();
if (start != end) {
text = text.subSequence(start, end);
}
AlertDialog progress = AlertUtil.showProgress(parentActivity);
progress.show();
String finalText = text.toString();
UIUtil.runOnIoDispatcher(() -> {
String ccText = CCConverter.get(CCTarget.valueOf(target)).convert(text);
String ccText = CCConverter.get(CCTarget.valueOf(target)).convert(finalText);
UIUtil.runOnUIThread(() -> {
progress.dismiss();
messageEditText.setText(ccText);
if (start == end) messageEditText.setText(ccText);
else messageEditText.getText().replace(start, end, ccText);
});
});
}
private void showReplace() {
int start = messageEditText.getSelectionStart();
int end = messageEditText.getSelectionEnd();
CharSequence text = messageEditText.getText();
if (start != end) {
text = text.subSequence(start, end);
}
BottomBuilder builder = new BottomBuilder(getContext());
builder.addTitle(LocaleController.getString("ReplaceText", R.string.ReplaceText), true);
TextCheckCell regex = builder.addCheckItem(LocaleController.getString("ReplaceRegex", R.string.ReplaceRegex), false, false, null);
EditText origin = builder.addEditText(LocaleController.getString("TextOrigin", R.string.TextOrigin));
EditText replace = builder.addEditText(LocaleController.getString("TextReplace", R.string.TextReplace));
String finalText = text.toString();
builder.addButton(LocaleController.getString("TextReplace", R.string.TextReplace), true, it -> {
String originText = origin.getText().toString();
String replaceText = replace.getText().toString();
if (originText.isEmpty()) {
AndroidUtilities.showKeyboard(origin);
}
boolean useRegex = regex.isChecked();
AlertDialog progress = AlertUtil.showProgress(getContext());
progress.show();
UIUtil.runOnIoDispatcher(() -> {
String replaced;
if (useRegex) {
replaced = ReUtil.replaceAll(finalText, originText, replaceText);
} else {
replaced = StrUtil.replace(finalText, originText, replaceText);
}
UIUtil.runOnUIThread(() -> {
if (start == end) messageEditText.setText(replaced);
else messageEditText.getText().replace(start, end, replaced);
progress.dismiss();
builder.dismiss();
});
});
return Unit.INSTANCE;
});
builder.addCancelButton();
builder.show();
}
public boolean isSendButtonVisible() {
return sendButton.getVisibility() == VISIBLE;
}
@ -4121,6 +4205,13 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
int fromRes;
int targetRes;
Object oldStatus = attachButton.getTag();
if (oldStatus != null) {
int osi = (int) oldStatus;
if (use && osi == 1) return;
if (!use & osi == 2) return;
}
isInInput = use;
if (duration == 0 && botButton != null) {
@ -4132,13 +4223,16 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
if (use) {
attachButton.setTag(1);
fromRes = R.drawable.deproko_baseline_attach_26;
targetRes = R.drawable.ic_ab_other;
attachButton.setOnClickListener(this::onMenuClick);
attachButton.setContentDescription(LocaleController.getString("AccDescrAttachButton", R.string.AccDescrChatAttachEnterMenu));
} else {
attachButton.setTag(2);
fromRes = R.drawable.ic_ab_other;
targetRes = R.drawable.deproko_baseline_attach_26;
@ -6437,10 +6531,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
private void updateBotButton() {
if (botButton == null) {
return;
}
if (hasBotCommands || botReplyMarkup != null) {
if (!checkBotButton()) return;
boolean textBlank = StrUtil.isBlank(AndroidUtilities.getTrimmedString(messageEditText.getText()));
if ((hasBotCommands || botReplyMarkup != null) && textBlank) {
if (botButton.getVisibility() != VISIBLE) {
botButton.setVisibility(VISIBLE);
}

View File

@ -1110,22 +1110,18 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
for (SubInfo sub : SubManager.getSubList().find()) {
TextCheckCell subItem = builder.addCheckItem(sub.name, sub.enable, true, (it) -> {
TextCheckCell subItem = builder.addCheckItem(sub.name, sub.enable, true, (it, target) -> {
boolean curr = (toChange.containsKey(sub) ? toChange.get(sub) : sub.enable);
if (curr != sub.enable) {
if (target == sub.enable) {
toChange.remove(sub);
} else {
toChange.put(sub, !sub.enable);
toChange.put(sub, target);
}
it.setChecked(!curr);
return Unit.INSTANCE;
});

View File

@ -482,42 +482,16 @@ public class StickersActivity extends BaseFragment implements NotificationCenter
builder.addCheckItems(new String[]{
LocaleController.getString("StickerSets", R.string.StickerSets),
LocaleController.getString("ArchivedStickers", R.string.ArchivedStickers)
}, (__) -> true, false, (index, text, cell) -> {
boolean export;
switch (index) {
case 0: {
export = exportSets.get();
exportSets.set(export = !export);
}
break;
default: {
export = exportArchived.get();
exportArchived.set(export = !export);
}
break;
}
cell.setChecked(export);
if (!exportSets.get() && !exportArchived.get()) {
exportButton.get().setEnabled(false);
}, (__) -> true, false, (index, text, cell, isChecked) -> {
if (index == 0) {
exportSets.set(isChecked);
} else {
exportButton.get().setEnabled(true);
exportArchived.set(isChecked);
}
exportButton.get().setEnabled(exportSets.get() || exportArchived.get());
return Unit.INSTANCE;
});

View File

@ -14,6 +14,7 @@ import org.telegram.ui.Cells.HeaderCell
import org.telegram.ui.Cells.RadioButtonCell
import org.telegram.ui.Cells.TextCell
import org.telegram.ui.Cells.TextCheckCell
import org.telegram.ui.Components.CheckBoxSquare
import org.telegram.ui.Components.LayoutHelper
import java.util.*
@ -108,7 +109,7 @@ class BottomBuilder(val ctx: Context) {
}
@JvmOverloads
fun addCheckItem(text: String, value: Boolean, switch: Boolean = false, valueText: String? = null, listener: (cell: TextCheckCell) -> Unit): TextCheckCell {
fun addCheckItem(text: String, value: Boolean, switch: Boolean = false, valueText: String? = null, listener: ((cell: TextCheckCell, isChecked: Boolean) -> Unit)?): TextCheckCell {
val checkBoxCell = TextCheckCell(ctx, 21, !switch)
checkBoxCell.setBackgroundDrawable(Theme.getSelectorDrawable(false))
@ -116,19 +117,21 @@ class BottomBuilder(val ctx: Context) {
rootView.addView(checkBoxCell, LayoutHelper.createLinear(-1, -2))
if (valueText == null) {
checkBoxCell.setTextAndCheck(text, value, true)
} else {
checkBoxCell.setTextAndValueAndCheck(text, valueText, value, true, true)
}
checkBoxCell.setOnClickListener {
val target = !checkBoxCell.isChecked
checkBoxCell.isChecked = target
listener?.invoke(checkBoxCell, target)
}
listener.invoke(checkBoxCell)
if (checkBoxCell.checkBox != null) {
checkBoxCell.checkBox.setOnClickListener { checkBoxCell.performClick() }
} else {
checkBoxCell.checkBoxSquare.setOnClickListener { checkBoxCell.performClick() }
}
return checkBoxCell
@ -136,18 +139,14 @@ class BottomBuilder(val ctx: Context) {
}
@JvmOverloads
fun addCheckItems(text: Array<String>, value: (Int) -> Boolean, switch: Boolean = false, valueText: ((Int) -> String)? = null, listener: (index: Int, text: String, cell: TextCheckCell) -> Unit): List<TextCheckCell> {
fun addCheckItems(text: Array<String>, value: (Int) -> Boolean, switch: Boolean = false, valueText: ((Int) -> String)? = null, listener: (index: Int, text: String, cell: TextCheckCell, isChecked: Boolean) -> Unit): List<TextCheckCell> {
val list = mutableListOf<TextCheckCell>()
text.forEachIndexed { index, textI ->
list.add(addCheckItem(textI, value(index), switch, valueText?.invoke(index)) { cell ->
listener(index, textI, cell)
list.add(addCheckItem(textI, value(index), switch, valueText?.invoke(index)) { cell, isChecked ->
listener(index, textI, cell, isChecked)
})
}
return list
@ -241,9 +240,9 @@ class BottomBuilder(val ctx: Context) {
@JvmOverloads
fun addOkButton(listener: ((TextView) -> Unit)) {
fun addOkButton(listener: ((TextView) -> Unit), noAutoDismiss: Boolean = false) {
addButton(LocaleController.getString("OK", R.string.OK)) { listener(it); }
addButton(LocaleController.getString("OK", R.string.OK), noAutoDismiss) { listener(it); }
}
@ -310,13 +309,13 @@ class BottomBuilder(val ctx: Context) {
}
@JvmOverloads
fun addItems(text: Array<String>, icon: (Int) -> Int = { 0 }, listener: (index: Int, text: String, cell: TextCell) -> Unit): List<TextCell> {
fun addItems(text: Array<String?>, icon: (Int) -> Int = { 0 }, listener: (index: Int, text: String, cell: TextCell) -> Unit): List<TextCell> {
val list = mutableListOf<TextCell>()
text.forEachIndexed { index, textI ->
list.add(addItem(textI, icon(index)) { cell ->
list.add(addItem(textI ?: return@forEachIndexed, icon(index)) { cell ->
listener(index, textI, cell)
@ -341,7 +340,7 @@ class BottomBuilder(val ctx: Context) {
isFocusable = true
setBackgroundDrawable(null)
this@BottomBuilder.rootView.addView(this, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, -2, if (LocaleController.isRTL) Gravity.RIGHT else Gravity.LEFT, AndroidUtilities.dp(8F), 0, 0, 0))
this@BottomBuilder.rootView.addView(this, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, -2, if (LocaleController.isRTL) Gravity.RIGHT else Gravity.LEFT, AndroidUtilities.dp(6F), 0, 0, 0))
}

View File

@ -0,0 +1,24 @@
package tw.nekomimi.nekogram.parts
private val mapArr = mapOf(
'' to '(',
'' to ')',
'。' to '.',
'' to ',',
'' to '?',
'' to ';'
)
fun filter(input: String) = input.toCharArray().let { c ->
c.flatMapIndexed { index, char ->
if (char in mapArr) {
if (c.size - index > 1 && c[index + 1] != ' ') {
listOf(mapArr[char], ' ')
} else {
listOf(mapArr[char])
}
} else {
listOf(char)
}
}.filterNotNull().toCharArray().let(::String)
}

View File

@ -270,5 +270,9 @@
<string name="TabletMode">Tablet mode</string>
<string name="TabletModeDefault">Depends on device</string>
<string name="ReplaceText">Replace Text</string>
<string name="TextOrigin">Origin</string>
<string name="TextReplace">Replace</string>
<string name="ReplaceRegex">Use regex</string>
</resources>