Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ android {

defaultConfig {
applicationId "ir.ninjacoder.code"
minSdk 21
minSdk 23
targetSdk 35
versionCode 1
versionName "1.0"
versionCode VERSION_CODE.toInteger()
versionName VERSION_NAME

vectorDrawables {
useSupportLibrary true
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/ir/ninjacoder/code/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ public void onCreate() {
super.onCreate();
ThemeLoader.init(this);
// TODO: Implement this method
LibraryLoader.load();
}
}
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ systemProp.file.encoding=UTF-8
org.gradle.jvmargs=-Xmx4g -Dfile.encoding\=UTF-8 -Dsun.jnu.encoding\=UTF-8 -Duser.language\=en -Duser.country\=US
android.useAndroidX=true
android.enableJetifier=true

VERSION_NAME=1.1.2
VERSION_CODE=2
Empty file modified gradlew
100644 → 100755
Empty file.
12 changes: 6 additions & 6 deletions snapcode/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ android {
compileSdk 35

defaultConfig {
minSdk 21
targetSdk 34
versionCode 1
versionName "1.1.1"
minSdk 23
targetSdk 35
versionCode VERSION_CODE.toInteger()
versionName VERSION_NAME
consumerProguardFiles "consumer-rules.pro"
}

Expand Down Expand Up @@ -60,7 +60,7 @@ dependencies {
exclude group: "org.jetbrains", module: "annotations-java5"
}

implementation("com.github.bumptech.glide:glide:5.0.0-rc01")
implementation("com.github.bumptech.glide:glide:5.0.5")
}

afterEvaluate {
Expand All @@ -72,7 +72,7 @@ afterEvaluate {

groupId = 'com.github.HanzoDev1375'
artifactId = 'CodeSnap'
version = '1.1.1'
version = VERSION_NAME

pom {
withXml {
Expand Down
7 changes: 6 additions & 1 deletion snapcode/src/main/java/ir/ninjacoder/codesnap/LangType.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public LangType getLangTypeFromPath(String filePath) {
}

public boolean hasFile(String file) {
return Arrays.stream(LangType.values()).allMatch(it -> file.endsWith(it.getLangname()));
for (LangType lang : LangType.values()) {
if (file.endsWith(lang.getLangname())) {
return true;
}
}
return false;
}
}
42 changes: 10 additions & 32 deletions snapcode/src/main/java/ir/ninjacoder/codesnap/LayoutGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,6 @@ public void init() {
drawable.setHighlightColor(color.getCardstorkecolor());

binding.editor.getCode().setForeground(drawable);
getCode()
.addTextChangedListener(
new TextWatcher() {

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}

@Override
public void afterTextChanged(Editable arg0) {
// highlightText(arg0.toString(), binding.editor.getCode());
}
});
color.addOnThemeChangeListener(
() -> {
updateTheme();
Expand Down Expand Up @@ -159,23 +144,15 @@ public void setText(String text) {
}

private void highlightText(String text, EditText editText) {
try {
CodeImpl code = new CodeImpl();
final SpannableStringBuilder highlightedText = code.highlight(type, text, color);
editText.setText(text);
animateOptimizedColorWave(editText, highlightedText);
binding
.getRoot()
.post(
() -> {
binding.eyeicon.setVisibility(type == LangType.MARKDOWN ? VISIBLE : GONE);
// binding.editor.showMarkDownView(type == LangType.MARKDOWN);
binding.eyeicon.invalidate();
});

} catch (Exception e) {
e.printStackTrace();
}
editText.setText(text);
binding
.getRoot()
.post(
() -> {
binding.eyeicon.setVisibility(type == LangType.MARKDOWN ? VISIBLE : GONE);
// binding.editor.showMarkDownView(type == LangType.MARKDOWN);
binding.eyeicon.invalidate();
});
}

void showIconCopy(boolean show) {
Expand Down Expand Up @@ -344,6 +321,7 @@ public LangType getType() {

public void setType(LangType type) {
this.type = type;
binding.editor.setLangType(type);
updateHighlight();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@
public class CodeHighlighterMarkdown implements Highlighter {

private static final HighlightRule[] RULES = {
// اول HTML tags چون پیچیده‌تره
new HighlightRule(Pattern.compile("<!--[\\s\\S]*?-->"), 7), // HTML Comments
new HighlightRule(Pattern.compile("</?[a-zA-Z][^>]*>"), 8), // HTML tags
new HighlightRule(Pattern.compile("`{3}[\\s\\S]*?`{3}"), 3), // Code blocks
new HighlightRule(Pattern.compile("!?\\[.*?\\]\\(.*?\\)"), 4), // Links - ساده‌شده
new HighlightRule(Pattern.compile("!?\\[.*?\\]\\(.*?\\)"), 4), // Links
new HighlightRule(Pattern.compile("^#{1,6}\\s+.*$", Pattern.MULTILINE), 1), // Headers
new HighlightRule(
Pattern.compile("\\*\\*\\*.*?\\*\\*\\*|\\*\\*.*?\\*\\*|\\*.*?\\*"), 2), // Bold/Italic
new HighlightRule(Pattern.compile("`[^`]*`"), 3), // Inline code
new HighlightRule(Pattern.compile("^\\s*[-*+]\\s+"), 5), // List bullets
new HighlightRule(Pattern.compile("^\\s*\\d+\\.\\s+"), 5), // Numbered lists
new HighlightRule(Pattern.compile("\\[[ x]\\]"), 6),
// الگوی جدید برای خط تیره‌های عمومی
new HighlightRule(Pattern.compile("-"), 9) // همه خط تیره‌ها
new HighlightRule(Pattern.compile("^\\s*[-*+]\\s+.*$", Pattern.MULTILINE), 5), // List bullets
new HighlightRule(Pattern.compile("^\\s*\\d+\\.\\s+.*$", Pattern.MULTILINE), 5), // Numbered lists
new HighlightRule(Pattern.compile("\\[[ x]\\]"), 6), // Checkboxes
new HighlightRule(Pattern.compile("---"), 9) // Horizontal rules
};

@Override
Expand All @@ -34,56 +33,17 @@ public SpannableStringBuilder highlight(LangType types, String code, ColorHelper
Matcher matcher = rule.pattern.matcher(code);
while (matcher.find()) {
int ruleColor = getColorForRule(rule.type, color);

// برای الگوی شماره 9 (خط تیره) فقط در موارد خاص رنگی شود
if (rule.type == 9) {
int position = matcher.start();
String matchedText = matcher.group();

// فقط اگر خط تیره باشد و در موقعیت مناسب باشد
if ("-".equals(matchedText)) {
// بررسی کن که این خط تیره بخشی از یک الگوی دیگر نباشد
if (!isPartOfOtherPattern(code, position)) {
builder.setSpan(
new ForegroundColorSpan(ruleColor),
position,
position + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
} else {
builder.setSpan(
new ForegroundColorSpan(ruleColor),
matcher.start(),
matcher.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
builder.setSpan(
new ForegroundColorSpan(ruleColor),
matcher.start(),
matcher.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

return builder;
}

// بررسی می‌کند که آیا کاراکتر در موقعیت داده شده بخشی از الگوی دیگر است یا نه
private boolean isPartOfOtherPattern(String code, int position) {
// اگر خط تیره بخشی از این الگوها باشد، آن را رنگی نکن
String surroundingText = getSurroundingText(code, position, 10);

// بررسی برای الگوهای دیگر
if (surroundingText.matches(".*\\[.*\\].*")) return true; // بخشی از لینک
if (surroundingText.matches(".*`.*`.*")) return true; // بخشی از کد
if (surroundingText.matches(".*\\*.*\\*.*")) return true; // بخشی از bold/italic
if (surroundingText.matches(".*<!--.*-->.*")) return true; // بخشی از کامنت HTML

return false;
}

private String getSurroundingText(String text, int position, int contextLength) {
int start = Math.max(0, position - contextLength);
int end = Math.min(text.length(), position + contextLength + 1);
return text.substring(start, end);
}

private int getColorForRule(int type, ColorHelper color) {
switch (type) {
case 1:
Expand All @@ -98,10 +58,12 @@ private int getColorForRule(int type, ColorHelper color) {
return color.getCsskeyword(); // Lists
case 6:
return color.getOperator(); // Checkboxes
case 7:
return color.getComment(); // HTML Comments
case 8:
return color.getHtmlkeyword(); // HTML tags
case 9:
return color.getLastsymi(); // خط تیره
return color.getLastsymi(); // Horizontal rules
default:
return color.getTextnormal();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ir.ninjacoder.codesnap.Utils;

import android.text.Editable;
import android.text.TextWatcher;
import ir.ninjacoder.codesnap.LangType;
import ir.ninjacoder.codesnap.colorhelper.ColorHelper;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.os.Handler;
import android.os.Looper;

public class IncrementalHighlighter implements TextWatcher {

private final Highlighter highlighter;
private final LangType langType;
private final ColorHelper colorHelper;
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final Handler handler = new Handler(Looper.getMainLooper());
private Editable editable;

public IncrementalHighlighter(Highlighter highlighter, LangType langType, ColorHelper colorHelper) {
this.highlighter = highlighter;
this.langType = langType;
this.colorHelper = colorHelper;
}

public void attach(Editable editable) {
this.editable = editable;
editable.setSpan(this, 0, editable.length(), 0);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// No-op
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// No-op
}

@Override
public void afterTextChanged(Editable s) {
executor.submit(() -> {
try {
// For simplicity, we are re-highlighting the entire text.
// A more optimized version would only highlight the changed region.
CharSequence highlighted = highlighter.highlight(langType, s.toString(), colorHelper);
handler.post(() -> {
s.clearSpans();
s.replace(0, s.length(), highlighted);
});
} catch (Exception e) {
// Handle exception
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ private void applyZoom() {
}

updateLineNumberWidth();
requestLayout();
invalidate();
// requestLayout();
// invalidate();
}

private void init() {
Expand Down Expand Up @@ -257,6 +257,8 @@ private void updateLineNumberWidth() {
int lineCount = getLineCount();
int maxDigits = Math.max(1, String.valueOf(Math.max(lineCount, 1)).length());

if (lineNumberPaint == null) return; // Prevent crash

float charWidth = lineNumberPaint.measureText("0");
float textWidth = charWidth * (maxDigits + 1);
lineNumberWidth = (int) textWidth + lineNumberPadding * 2;
Expand Down Expand Up @@ -429,8 +431,9 @@ public boolean onScale(ScaleGestureDetector detector) {
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
isZooming = false;
invalidate();
// invalidate(); // This will be handled by the zoom logic now
super.onScaleEnd(detector);
postInvalidate(); // More efficient redraw
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
import com.google.android.material.tooltip.TooltipDrawable;
import ir.ninjacoder.codesnap.R;
import ir.ninjacoder.codesnap.Utils.ObjectUtils;
import ir.ninjacoder.codesnap.Utils.IncrementalHighlighter;
import ir.ninjacoder.codesnap.LangType;
import ir.ninjacoder.codesnap.Utils.Highlighter;
import ir.ninjacoder.codesnap.Utils.CodeImpl;
import ir.ninjacoder.codesnap.colorhelper.ColorHelper;
import ir.ninjacoder.codesnap.folding.CodeFoldingManager;
import ir.ninjacoder.codesnap.markdownpreview.MarkDownTextHelper;
Expand All @@ -50,6 +54,7 @@ public class SyntaxView extends ScrollView {
private TextView tv;
private String oldText = "";
private TextWatcher textWatcher;
private IncrementalHighlighter incrementalHighlighter;
private boolean isMarkdownMode = false;
private TooltipDrawable tooltip;
private boolean isTooltipShowing = false;
Expand Down Expand Up @@ -234,7 +239,13 @@ public void afterTextChanged(Editable s) {
}
};

code.addTextChangedListener(textWatcher);
// code.addTextChangedListener(textWatcher);
}

public void setLangType(LangType langType) {
Highlighter highlighter = new CodeImpl();
incrementalHighlighter = new IncrementalHighlighter(highlighter, langType, color);
incrementalHighlighter.attach(code.getText());
}

private char getLastDifference(String a, String b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RotateDrawable;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.shape.MaterialShapes;
import com.google.android.material.slider.Slider;
import android.util.AttributeSet;
import ir.ninjacoder.codesnap.R;
Expand Down