From 211fdab2505ffe5acc19d633ace67d8bf65e413a Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Fri, 30 Sep 2022 05:04:01 +0200 Subject: [PATCH 1/2] Move syntax highligting to codeview components (#1196) TODO - Issues of https://codeberg.org/gitnex-garage/useLangDefs https://codeberg.org/gitnex/GitNex/issues/1180 Also see https://codeberg.org/gitnex-garage/useLangDefs Co-authored-by: qwerty287 Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1196 Reviewed-by: M M Arif Co-authored-by: qwerty287 Co-committed-by: qwerty287 --- README.md | 1 - app/build.gradle | 2 - .../gitnex/activities/CodeEditorActivity.java | 44 ++- .../mian/gitnex/core/MainGrammarLocator.java | 49 +-- .../org/mian/gitnex/helpers/Markdown.java | 29 +- .../helpers/codeeditor/LanguageManager.java | 136 -------- .../helpers/codeeditor/LanguageName.java | 15 - .../codeeditor/SourcePositionListener.java | 12 +- .../gitnex/helpers/codeeditor/ThemeName.java | 9 - .../codeeditor/languages/CLanguage.java | 164 ++++++++++ .../codeeditor/languages/CppLanguage.java | 154 +++++++++ .../codeeditor/languages/GoLanguage.java | 161 ++++++---- .../codeeditor/languages/HtmlLanguage.java | 215 ++++++++----- .../codeeditor/languages/JavaLanguage.java | 201 +++++++----- .../languages/JavaScriptLanguage.java | 168 ++++++++++ .../codeeditor/languages/JsonLanguage.java | 98 ++++++ .../codeeditor/languages/Language.java | 91 ++++++ .../codeeditor/languages/LanguageElement.java | 20 ++ .../codeeditor/languages/PhpLanguage.java | 224 ++++++++----- .../codeeditor/languages/PythonLanguage.java | 177 +++++----- .../languages/TypeScriptLanguage.java | 21 ++ .../codeeditor/languages/UnknownLanguage.java | 43 +++ .../codeeditor/languages/XmlLanguage.java | 114 ++++--- .../markwon/MarkwonHighlighter.java | 47 +++ .../codeeditor/markwon/SyntaxHighlighter.java | 77 +++++ .../codeeditor/theme/FiveColorsDarkTheme.java | 51 +++ .../codeeditor/theme/FiveColorsTheme.java | 51 +++ .../helpers/codeeditor/theme/Theme.java | 32 ++ .../gitnex/views/SyntaxHighlightedArea.java | 41 +-- app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/languages.xml | 304 ------------------ 31 files changed, 1740 insertions(+), 1013 deletions(-) delete mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageManager.java delete mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageName.java delete mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/ThemeName.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CppLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaScriptLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JsonLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/Language.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/LanguageElement.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/TypeScriptLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/UnknownLanguage.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/MarkwonHighlighter.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/SyntaxHighlighter.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsDarkTheme.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsTheme.java create mode 100644 app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/Theme.java delete mode 100644 app/src/main/res/values/languages.xml diff --git a/README.md b/README.md index e118d1cd..a22cc522 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,6 @@ Thanks to all the open source libraries, contributors and donators. - [wasabeef/picasso-transformations](https://github.com/wasabeef/picasso-transformations) - [cats-oss/android-gpuimage](https://github.com/cats-oss/android-gpuimage) - [noties/Markwon](https://github.com/noties/Markwon) -- [noties/Prism4j](https://github.com/noties/Prism4j) - [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime) - [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable) - [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java) diff --git a/app/build.gradle b/app/build.gradle index 2fc74cce..aabbedae 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,8 +94,6 @@ dependencies { implementation "io.noties.markwon:recycler:$markwon_version" implementation "io.noties.markwon:recycler-table:$markwon_version" implementation "io.noties.markwon:simple-ext:$markwon_version" - implementation 'org.codeberg.qwerty287:markwonprism4j:9d3ef078cd' - implementation 'org.codeberg.qwerty287:Prism4j:3.0.0' implementation 'com.google.guava:guava:31.1-android' implementation "io.noties.markwon:image-picasso:$markwon_version" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" diff --git a/app/src/main/java/org/mian/gitnex/activities/CodeEditorActivity.java b/app/src/main/java/org/mian/gitnex/activities/CodeEditorActivity.java index fb007158..3776430b 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CodeEditorActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CodeEditorActivity.java @@ -10,14 +10,14 @@ import com.amrdeveloper.codeview.Code; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.EnumUtils; import org.mian.gitnex.R; +import org.mian.gitnex.core.MainGrammarLocator; import org.mian.gitnex.databinding.ActivityCodeEditorBinding; import org.mian.gitnex.helpers.codeeditor.CustomCodeViewAdapter; -import org.mian.gitnex.helpers.codeeditor.LanguageManager; -import org.mian.gitnex.helpers.codeeditor.LanguageName; import org.mian.gitnex.helpers.codeeditor.SourcePositionListener; -import org.mian.gitnex.helpers.codeeditor.ThemeName; +import org.mian.gitnex.helpers.codeeditor.languages.Language; +import org.mian.gitnex.helpers.codeeditor.languages.UnknownLanguage; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; /** * @author AmrDeveloper @@ -25,10 +25,9 @@ import org.mian.gitnex.helpers.codeeditor.ThemeName; */ public class CodeEditorActivity extends BaseActivity { - private final ThemeName currentTheme = ThemeName.FIVE_COLOR; + private Theme currentTheme; private ActivityCodeEditorBinding binding; - private LanguageManager languageManager; - private LanguageName currentLanguage = LanguageName.UNKNOWN; + private Language currentLanguage = new UnknownLanguage(); @Override public void onCreate(Bundle savedInstanceState) { @@ -44,15 +43,13 @@ public class CodeEditorActivity extends BaseActivity { String fileContent = getIntent().getStringExtra("fileContent"); String fileExtension; + currentTheme = Theme.getDefaultTheme(this); if (getIntent().getStringExtra("fileExtension") != null) { - fileExtension = getIntent().getStringExtra("fileExtension").toUpperCase(); + fileExtension = + MainGrammarLocator.fromExtension(getIntent().getStringExtra("fileExtension")); - if (EnumUtils.isValidEnum(LanguageName.class, fileExtension)) { - currentLanguage = LanguageName.valueOf(fileExtension); - } else { - currentLanguage = LanguageName.UNKNOWN; - } + currentLanguage = Language.fromName(fileExtension); } configCodeView(currentLanguage, fileContent); @@ -65,7 +62,7 @@ public class CodeEditorActivity extends BaseActivity { setResult(Activity.RESULT_OK, intent); } - private void configCodeView(LanguageName currentLanguage, String fileContent) { + private void configCodeView(Language currentLanguage, String fileContent) { binding.codeView.setTypeface( Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf")); @@ -79,9 +76,8 @@ public class CodeEditorActivity extends BaseActivity { binding.codeView.setTabLength(4); binding.codeView.setEnableAutoIndentation(true); - // Setup the language and theme with SyntaxManager helper class - languageManager = new LanguageManager(this, binding.codeView); - languageManager.applyTheme(currentLanguage, currentTheme); + // Set up the language and theme with SyntaxManager helper class + currentLanguage.applyTheme(this, binding.codeView, currentTheme); // Setup auto pair complete final Map pairCompleteMap = new HashMap<>(); @@ -97,7 +93,7 @@ public class CodeEditorActivity extends BaseActivity { binding.codeView.enablePairCompleteCenterCursor(true); binding.codeView.setText(fileContent); - // Setup the auto complete and auto indenting for the current language + // Set up the auto complete and auto indenting for the current language configLanguageAutoComplete(); configLanguageAutoIndentation(); } @@ -106,13 +102,13 @@ public class CodeEditorActivity extends BaseActivity { boolean useModernAutoCompleteAdapter = true; if (useModernAutoCompleteAdapter) { - List codeList = languageManager.getLanguageCodeList(currentLanguage); + List codeList = currentLanguage.getCodeList(); CustomCodeViewAdapter adapter = new CustomCodeViewAdapter(this, codeList); binding.codeView.setAdapter(adapter); } else { - String[] languageKeywords = languageManager.getLanguageKeywords(currentLanguage); + String[] languageKeywords = currentLanguage.getKeywords(); final int layoutId = R.layout.list_item_suggestion; @@ -125,10 +121,8 @@ public class CodeEditorActivity extends BaseActivity { } private void configLanguageAutoIndentation() { - binding.codeView.setIndentationStarts( - languageManager.getLanguageIndentationStarts(currentLanguage)); - binding.codeView.setIndentationEnds( - languageManager.getLanguageIndentationEnds(currentLanguage)); + binding.codeView.setIndentationStarts(currentLanguage.getIndentationStarts()); + binding.codeView.setIndentationEnds(currentLanguage.getIndentationEnds()); } private void configCodeViewPlugins() { @@ -139,7 +133,7 @@ public class CodeEditorActivity extends BaseActivity { } private void configLanguageName() { - binding.languageName.setText(currentLanguage.name().toLowerCase()); + binding.languageName.setText(currentLanguage.getName().toLowerCase()); } private void configSourcePositionListener() { diff --git a/app/src/main/java/org/mian/gitnex/core/MainGrammarLocator.java b/app/src/main/java/org/mian/gitnex/core/MainGrammarLocator.java index 24dd7159..596a3d99 100644 --- a/app/src/main/java/org/mian/gitnex/core/MainGrammarLocator.java +++ b/app/src/main/java/org/mian/gitnex/core/MainGrammarLocator.java @@ -1,38 +1,13 @@ package org.mian.gitnex.core; -import androidx.annotation.NonNull; -import io.noties.prism4j.DefaultGrammarLocator; -import io.noties.prism4j.Grammar; -import io.noties.prism4j.GrammarLocator; -import io.noties.prism4j.Prism4j; -import java.util.Set; - /** * @author opyale */ -public class MainGrammarLocator implements GrammarLocator { +public class MainGrammarLocator { - public static final String DEFAULT_FALLBACK_LANGUAGE = "clike"; + public static final String DEFAULT_FALLBACK_LANGUAGE = null; // "clike"; - private static final DefaultGrammarLocator defaultGrammarLocator = new DefaultGrammarLocator(); - private static volatile MainGrammarLocator instance; - - private MainGrammarLocator() {} - - public static MainGrammarLocator getInstance() { - - if (instance == null) { - synchronized (MainGrammarLocator.class) { - if (instance == null) { - instance = new MainGrammarLocator(); - } - } - } - - return instance; - } - - public String fromExtension(String extension) { + public static String fromExtension(String extension) { switch (extension.toLowerCase()) { case "b": @@ -84,9 +59,9 @@ public class MainGrammarLocator implements GrammarLocator { case "md": return "markdown"; - case "xml": - case "html": - case "htm": + // case "xml": + // case "html": + // case "htm": case "mathml": case "svg": return "markup"; @@ -113,16 +88,4 @@ public class MainGrammarLocator implements GrammarLocator { return extension; } - - @Override - public Grammar grammar(@NonNull Prism4j prism4j, @NonNull String language) { - - return defaultGrammarLocator.grammar(prism4j, language); - } - - @NonNull @Override - public Set languages() { - - return defaultGrammarLocator.languages(); - } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/Markdown.java b/app/src/main/java/org/mian/gitnex/helpers/Markdown.java index d90278d9..9a62ca0b 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/Markdown.java +++ b/app/src/main/java/org/mian/gitnex/helpers/Markdown.java @@ -9,10 +9,6 @@ import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import de.qwerty287.markwonprism4j.Prism4jTheme; -import de.qwerty287.markwonprism4j.Prism4jThemeDarkula; -import de.qwerty287.markwonprism4j.Prism4jThemeDefault; -import de.qwerty287.markwonprism4j.SyntaxHighlightPlugin; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; @@ -33,7 +29,6 @@ import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.SimpleEntry; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; -import io.noties.prism4j.Prism4j; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; @@ -58,6 +53,8 @@ import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.activities.ProfileActivity; import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.core.MainGrammarLocator; +import org.mian.gitnex.helpers.codeeditor.markwon.MarkwonHighlighter; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.helpers.contexts.RepositoryContext; import stormpot.Allocator; @@ -177,11 +174,6 @@ public class Markdown { private void setup() { - Prism4jTheme prism4jTheme = - AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 - ? Prism4jThemeDarkula.create() - : Prism4jThemeDefault.create(); - Markwon.Builder builder = Markwon.builder(context) .usePlugin(CorePlugin.create()) @@ -197,9 +189,9 @@ public class Markdown { PicassoImagesPlugin.create( PicassoService.getInstance(context).get())) .usePlugin( - SyntaxHighlightPlugin.create( - new Prism4j(MainGrammarLocator.getInstance()), - prism4jTheme, + MarkwonHighlighter.create( + context, + Theme.getDefaultTheme(context), MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)) .usePlugin( new AbstractMarkwonPlugin() { @@ -333,11 +325,6 @@ public class Markdown { linkPostProcessor.repository = repository; } - Prism4jTheme prism4jTheme = - AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 - ? Prism4jThemeDarkula.create() - : Prism4jThemeDefault.create(); - final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder() .addInlineProcessor(new IssueInlineProcessor()) @@ -359,9 +346,9 @@ public class Markdown { PicassoImagesPlugin.create( PicassoService.getInstance(context).get())) .usePlugin( - SyntaxHighlightPlugin.create( - new Prism4j(MainGrammarLocator.getInstance()), - prism4jTheme, + MarkwonHighlighter.create( + context, + Theme.getDefaultTheme(context), MainGrammarLocator.DEFAULT_FALLBACK_LANGUAGE)) .usePlugin( new AbstractMarkwonPlugin() { diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageManager.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageManager.java deleted file mode 100644 index aeb70de5..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageManager.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.mian.gitnex.helpers.codeeditor; - -import android.content.Context; -import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.mian.gitnex.helpers.codeeditor.languages.GoLanguage; -import org.mian.gitnex.helpers.codeeditor.languages.HtmlLanguage; -import org.mian.gitnex.helpers.codeeditor.languages.JavaLanguage; -import org.mian.gitnex.helpers.codeeditor.languages.PhpLanguage; -import org.mian.gitnex.helpers.codeeditor.languages.PythonLanguage; -import org.mian.gitnex.helpers.codeeditor.languages.XmlLanguage; - -/** - * @author AmrDeveloper - * @author M M Arif - */ -public class LanguageManager { - - private final Context context; - private final CodeView codeView; - - public LanguageManager(Context context, CodeView codeView) { - this.context = context; - this.codeView = codeView; - } - - public void applyTheme(LanguageName language, ThemeName theme) { - - if (theme == ThemeName.FIVE_COLOR) { - applyFiveColorsDarkTheme(language); - } - } - - public String[] getLanguageKeywords(LanguageName language) { - switch (language) { - case JAVA: - return JavaLanguage.getKeywords(context); - case PY: - return PythonLanguage.getKeywords(context); - case GO: - return GoLanguage.getKeywords(context); - case PHP: - return PhpLanguage.getKeywords(context); - case XML: - return XmlLanguage.getKeywords(context); - case HTML: - return HtmlLanguage.getKeywords(context); - default: - return new String[] {}; - } - } - - public List getLanguageCodeList(LanguageName language) { - switch (language) { - case JAVA: - return JavaLanguage.getCodeList(context); - case PY: - return PythonLanguage.getCodeList(context); - case GO: - return GoLanguage.getCodeList(context); - case PHP: - return PhpLanguage.getCodeList(context); - case XML: - return XmlLanguage.getCodeList(context); - case HTML: - return HtmlLanguage.getCodeList(context); - default: - return new ArrayList<>(); - } - } - - public Set getLanguageIndentationStarts(LanguageName language) { - switch (language) { - case JAVA: - return JavaLanguage.getIndentationStarts(); - case PY: - return PythonLanguage.getIndentationStarts(); - case GO: - return GoLanguage.getIndentationStarts(); - case PHP: - return PhpLanguage.getIndentationStarts(); - case XML: - return XmlLanguage.getIndentationStarts(); - case HTML: - return HtmlLanguage.getIndentationStarts(); - default: - return new HashSet<>(); - } - } - - public Set getLanguageIndentationEnds(LanguageName language) { - switch (language) { - case JAVA: - return JavaLanguage.getIndentationEnds(); - case PY: - return PythonLanguage.getIndentationEnds(); - case GO: - return GoLanguage.getIndentationEnds(); - case PHP: - return PhpLanguage.getIndentationEnds(); - case XML: - return XmlLanguage.getIndentationEnds(); - case HTML: - return HtmlLanguage.getIndentationEnds(); - default: - return new HashSet<>(); - } - } - - private void applyFiveColorsDarkTheme(LanguageName language) { - switch (language) { - case JAVA: - JavaLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - case PY: - PythonLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - case GO: - GoLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - case PHP: - PhpLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - case XML: - XmlLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - case HTML: - HtmlLanguage.applyFiveColorsDarkTheme(context, codeView); - break; - } - } -} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageName.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageName.java deleted file mode 100644 index b1cd9047..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/LanguageName.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mian.gitnex.helpers.codeeditor; - -/** - * @author AmrDeveloper - * @author M M Arif - */ -public enum LanguageName { - UNKNOWN, // no language is specified or app currently does not support the mentioned language - JAVA, // java - PY, // python with py extension - GO, // go lang - PHP, // php - XML, // xml - HTML // html -} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/SourcePositionListener.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/SourcePositionListener.java index 363faa24..0e761770 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/SourcePositionListener.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/SourcePositionListener.java @@ -11,12 +11,6 @@ import android.widget.EditText; */ public class SourcePositionListener { - @FunctionalInterface - public interface OnPositionChanged { - - void onPositionChange(int line, int column); - } - private OnPositionChanged onPositionChanged; public SourcePositionListener(EditText editText) { @@ -45,4 +39,10 @@ public class SourcePositionListener { public void setOnPositionChanged(OnPositionChanged listener) { onPositionChanged = listener; } + + @FunctionalInterface + public interface OnPositionChanged { + + void onPositionChange(int line, int column); + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/ThemeName.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/ThemeName.java deleted file mode 100644 index 8c148dd5..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/ThemeName.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mian.gitnex.helpers.codeeditor; - -/** - * @author AmrDeveloper - * @author M M Arif - */ -public enum ThemeName { - FIVE_COLOR -} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CLanguage.java new file mode 100644 index 00000000..5a5be239 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CLanguage.java @@ -0,0 +1,164 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import com.amrdeveloper.codeview.Code; +import com.amrdeveloper.codeview.Keyword; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author qwerty287 + */ +public class CLanguage extends Language { + + private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + private static final Pattern PATTERN_MULTI_LINE_COMMENT = + Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); + private static final Pattern PATTERN_OPERATION = + Pattern.compile( + ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); + private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); + private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); + private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); + private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); + + public static String getCommentStart() { + return "//"; + } + + public static String getCommentEnd() { + return ""; + } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case GENERIC: + case ANNOTATION: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + "alignas", + "alignof", + "auto", + "bool", + "break", + "case", + "char", + "const", + "constexpr", + "continue", + "default", + "do", + "double", + "else", + "enum", + "extern", + "false", + "float", + "for", + "goto", + "if", + "inline", + "int", + "long", + "nullptr", + "register", + "restrict", + "return", + "short", + "signed", + "sizeof", + "static", + "static_assert", + "struct", + "switch", + "thread_local", + "true", + "typedef", + "typeof", + "typeof_unqual", + "union", + "unsigned", + "void", + "volatile", + "while", + "_Alignas", + "_Alignof", + "_Atomic", + "_BitInt", + "_Bool", + "_Complex", + "_Decimal128", + "_Decimal32", + "_Decimal64", + "_Generic", + "_Imaginary", + "_Noreturn", + "_Static_assert", + "_Thread_local", + }; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "C"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CppLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CppLanguage.java new file mode 100644 index 00000000..38bc83ff --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/CppLanguage.java @@ -0,0 +1,154 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import com.amrdeveloper.codeview.Code; +import com.amrdeveloper.codeview.Keyword; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author qwerty287 + */ +public class CppLanguage extends Language { + + private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + private static final Pattern PATTERN_MULTI_LINE_COMMENT = + Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); + private static final Pattern PATTERN_OPERATION = + Pattern.compile( + ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); + private static final Pattern PATTERN_GENERIC = Pattern.compile("<[a-zA-Z0-9,<>]+>"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); + private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); + private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); + private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); + private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); + + public static String getCommentStart() { + return "//"; + } + + public static String getCommentEnd() { + return ""; + } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case GENERIC: + return PATTERN_GENERIC; + case ANNOTATION: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + "asm double", + "new", + "switch", + "auto", + "else", + "operator", + "template", + "break", + "enum", + "private", + "this", + "case", + "extern", + "protected", + "throw", + "catch", + "float", + "public", + "try", + "char", + "for", + "register", + "typedef", + "class", + "friend", + "return", + "union", + "const", + "goto", + "short", + "unsigned", + "continue", + "if", + "signed", + "virtual", + "default", + "inline", + "sizeof", + "void", + "delete", + "int", + "static", + "volatile", + "do", + "long", + "struct", + "while" + }; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "Cpp"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/GoLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/GoLanguage.java index c6b0f71a..3c009e61 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/GoLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/GoLanguage.java @@ -1,30 +1,18 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author AmrDeveloper * @author M M Arif */ -public class GoLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile( - "\\b(break|default|func|interface|case|defer|" - + "go|map|struct|chan|else|goto|package|switch|const" - + "|fallthrough|if|range|type|continue|for|import|return|var|" - + "string|true|false|new|nil|byte|bool|int|int8|int16|int32|int64)\\b"); +public class GoLanguage extends Language { // Brackets and Colons private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); @@ -32,9 +20,12 @@ public class GoLanguage { // Data private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); - private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); + private static final Pattern PATTERN_STRING = Pattern.compile("[\"`](.*?)[\"`]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); @@ -42,71 +33,121 @@ public class GoLanguage { Pattern.compile( ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.reHighlightSyntax(); + @Override + public String[] getKeywords() { + return new String[] { + "break", + "default", + "func", + "interface", + "select", + "case", + "defer", + "go", + "map", + "struct", + "chan", + "else", + "goto", + "package", + "switch", + "const", + "fallthrough", + "if", + "bool", + "byte", + "cap", + "close", + "complex", + "complex64", + "complex128", + "uint16", + "copy", + "false", + "float32", + "float64", + "imag", + "int", + "int8", + "int16", + "uint32", + "int32", + "int64", + "len", + "make", + "new", + "nil", + "uint64", + "range", + "type", + "continue", + "for", + "import", + "return", + "var" + }; } - public static String[] getKeywords(Context context) { - return context.getResources().getStringArray(R.array.go_keywords); - } - - public static List getCodeList(Context context) { + @Override + public List getCodeList() { List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); + String[] keywords = getKeywords(); for (String keyword : keywords) { codeList.add(new Keyword(keyword)); } return codeList; } - public static Set getIndentationStarts() { + @Override + public String getName() { + return "Go"; + } + + @Override + public Set getIndentationStarts() { Set characterSet = new HashSet<>(); characterSet.add('{'); return characterSet; } - public static Set getIndentationEnds() { + @Override + public Set getIndentationEnds() { Set characterSet = new HashSet<>(); characterSet.add('}'); return characterSet; } - public static String getCommentStart() { - return "//"; - } + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; - public static String getCommentEnd() { - return ""; + case GENERIC: + // TODO supported by Go 1.18 + case ANNOTATION: + default: + return null; + } } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/HtmlLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/HtmlLanguage.java index 504a92ca..a06a046b 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/HtmlLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/HtmlLanguage.java @@ -1,29 +1,17 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author M M Arif */ -public class HtmlLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile( - "\\b(]{}()]"); @@ -33,74 +21,12 @@ public class HtmlLanguage { private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); - private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); - private static final Pattern PATTERN_MULTI_LINE_COMMENT = - Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile(""); private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); private static final Pattern PATTERN_OPERATION = Pattern.compile( ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.reHighlightSyntax(); - } - - public static String[] getKeywords(Context context) { - return context.getResources().getStringArray(R.array.html_keywords); - } - - public static List getCodeList(Context context) { - List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); - for (String keyword : keywords) { - codeList.add(new Keyword(keyword)); - } - return codeList; - } - - public static Set getIndentationStarts() { - Set characterSet = new HashSet<>(); - characterSet.add('{'); - return characterSet; - } - - public static Set getIndentationEnds() { - Set characterSet = new HashSet<>(); - characterSet.add('}'); - return characterSet; - } - public static String getCommentStart() { return "//"; } @@ -108,4 +34,141 @@ public class HtmlLanguage { public static String getCommentEnd() { return ""; } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + case MULTI_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case GENERIC: + case TODO_COMMENT: + case ANNOTATION: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + " getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "HTML"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaLanguage.java index a77e2d3d..a3db178a 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaLanguage.java @@ -1,33 +1,18 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author AmrDeveloper * @author M M Arif */ -public class JavaLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile( - "\\b(abstract|boolean|break|byte|case|catch" - + "|char|class|continue|default|do|double|else" - + "|enum|extends|final|finally|float|for|if" - + "|implements|import|instanceof|int|interface" - + "|long|native|new|null|package|private|protected" - + "|public|return|short|static|strictfp|super|switch" - + "|synchronized|this|throw|transient|try|void|volatile|while)\\b"); +public class JavaLanguage extends Language { private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); @@ -39,78 +24,13 @@ public class JavaLanguage { ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); private static final Pattern PATTERN_GENERIC = Pattern.compile("<[a-zA-Z0-9,<>]+>"); private static final Pattern PATTERN_ANNOTATION = Pattern.compile("@.[a-zA-Z0-9]+"); - private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("//TODO[^\n]*"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ANNOTATION, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_GENERIC, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null)); - - codeView.reHighlightSyntax(); - } - - public static String[] getKeywords(Context context) { - return context.getResources().getStringArray(R.array.java_keywords); - } - - public static List getCodeList(Context context) { - List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); - for (String keyword : keywords) { - codeList.add(new Keyword(keyword)); - } - return codeList; - } - - public static Set getIndentationStarts() { - Set characterSet = new HashSet<>(); - characterSet.add('{'); - return characterSet; - } - - public static Set getIndentationEnds() { - Set characterSet = new HashSet<>(); - characterSet.add('}'); - return characterSet; - } - public static String getCommentStart() { return "//"; } @@ -118,4 +38,119 @@ public class JavaLanguage { public static String getCommentEnd() { return ""; } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case GENERIC: + return PATTERN_GENERIC; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case ANNOTATION: + return PATTERN_ANNOTATION; + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + "public", + "private", + "protected", + "package", + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "continue", + "default", + "do", + "double", + "else", + "enum", + "extends", + "final", + "finally", + "float", + "for", + "if", + "implements", + "import", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "return", + "short", + "static", + "strictfp", + "super", + "switch", + "synchronized", + "this", + "throw", + "transient", + "try", + "void", + "volatile", + "while" + }; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "Java"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaScriptLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaScriptLanguage.java new file mode 100644 index 00000000..49b2f93d --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JavaScriptLanguage.java @@ -0,0 +1,168 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import com.amrdeveloper.codeview.Code; +import com.amrdeveloper.codeview.Keyword; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author qwerty287 + */ +public class JavaScriptLanguage extends Language { + + private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + private static final Pattern PATTERN_MULTI_LINE_COMMENT = + Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); + private static final Pattern PATTERN_OPERATION = + Pattern.compile( + ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); + private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); + private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); + private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); + private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); + + public static String getCommentStart() { + return "//"; + } + + public static String getCommentEnd() { + return ""; + } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case ANNOTATION: + case GENERIC: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + "abstract", + "arguments", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "double", + "else", + "eval", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "in", + "instanceof", + "int", + "interface", + "let", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "typeof", + "var", + "void", + "volatile", + "while", + "with", + "yield", + "class", + "enum", + "export", + "extends", + "import", + "super" + }; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "JavaScript"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JsonLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JsonLanguage.java new file mode 100644 index 00000000..2d463c39 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/JsonLanguage.java @@ -0,0 +1,98 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import com.amrdeveloper.codeview.Code; +import com.amrdeveloper.codeview.Keyword; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author qwerty287 + */ +public class JsonLanguage extends Language { + + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + private static final Pattern PATTERN_MULTI_LINE_COMMENT = + Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("//\\s?(TODO|todo)\\s[^\n]*"); + private static final Pattern PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b"); + private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); + private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); + + public static String getCommentStart() { + return "//"; + } + + public static String getCommentEnd() { + return ""; + } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case BUILTIN: + case OPERATION: + case ANNOTATION: + case HEX: + case GENERIC: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] {"false", "true", "null"}; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "JSON"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + characterSet.add('['); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + characterSet.add(']'); + return characterSet; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/Language.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/Language.java new file mode 100644 index 00000000..3e7b4bcd --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/Language.java @@ -0,0 +1,91 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import android.content.Context; +import android.content.res.Resources; +import com.amrdeveloper.codeview.Code; +import com.amrdeveloper.codeview.CodeView; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Pattern; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; + +/** + * @author qwerty287 + */ +public abstract class Language { + + private static HashMap languages = null; + + private static void initializeMap() { + if (languages == null) { + languages = new HashMap<>(); + + Language[] languagesArray = + new Language[] { + new JavaLanguage(), + new PythonLanguage(), + new GoLanguage(), + new PhpLanguage(), + new XmlLanguage(), + new HtmlLanguage(), + new JavaScriptLanguage(), + new TypeScriptLanguage(), + new JsonLanguage(), + new CppLanguage(), + new CLanguage() + }; + for (Language l : languagesArray) { + languages.put(l.getName().toUpperCase(), l); + } + } + } + + public static Language fromName(String name) { + initializeMap(); + + return isValid(name) ? languages.get(name.toUpperCase()) : new UnknownLanguage(); + } + + public static boolean isValid(String name) { + initializeMap(); + + return languages.containsKey(name.toUpperCase()); + } + + public abstract Pattern getPattern(LanguageElement element); + + public abstract Set getIndentationStarts(); + + public abstract Set getIndentationEnds(); + + public abstract String[] getKeywords(); + + public abstract List getCodeList(); + + public abstract String getName(); + + public void applyTheme(Context context, CodeView codeView, Theme theme) { + codeView.resetSyntaxPatternList(); + codeView.resetHighlighter(); + + Resources resources = context.getResources(); + + // View Background + codeView.setBackgroundColor(resources.getColor(theme.getBackgroundColor(), null)); + + // Syntax Colors + for (LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) { + Pattern p = getPattern(e); + if (p != null) { + codeView.addSyntaxPattern(p, resources.getColor(theme.getColor(e), null)); + } + } + + // Default Color + codeView.setTextColor(resources.getColor(theme.getDefaultColor(), null)); + + codeView.reHighlightSyntax(); + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/LanguageElement.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/LanguageElement.java new file mode 100644 index 00000000..12e4847f --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/LanguageElement.java @@ -0,0 +1,20 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +/** + * @author qwerty287 + */ +public enum LanguageElement { + KEYWORD, + ATTRIBUTE, + BUILTIN, + NUMBER, + HEX, + OPERATION, + GENERIC, + ANNOTATION, + CHAR, + STRING, + SINGLE_LINE_COMMENT, + TODO_COMMENT, + MULTI_LINE_COMMENT +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PhpLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PhpLanguage.java index 08df1cc6..f66c6317 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PhpLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PhpLanguage.java @@ -1,31 +1,17 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author M M Arif */ -public class PhpLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile( - "\\b(]{}()]"); @@ -35,74 +21,16 @@ public class PhpLanguage { private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); - private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("(//|#)[^\\n]*"); private static final Pattern PATTERN_MULTI_LINE_COMMENT = Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); - private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("(//|#)\\s?(TODO|todo)\\s[^\\n]*"); + private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("(?<=->)[a-zA-Z0-9_]+"); private static final Pattern PATTERN_OPERATION = Pattern.compile( ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.reHighlightSyntax(); - } - - public static String[] getKeywords(Context context) { - return context.getResources().getStringArray(R.array.php_keywords); - } - - public static List getCodeList(Context context) { - List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); - for (String keyword : keywords) { - codeList.add(new Keyword(keyword)); - } - return codeList; - } - - public static Set getIndentationStarts() { - Set characterSet = new HashSet<>(); - characterSet.add('{'); - return characterSet; - } - - public static Set getIndentationEnds() { - Set characterSet = new HashSet<>(); - characterSet.add('}'); - return characterSet; - } - public static String getCommentStart() { return "//"; } @@ -110,4 +38,146 @@ public class PhpLanguage { public static String getCommentEnd() { return ""; } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case MULTI_LINE_COMMENT: + return PATTERN_MULTI_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case ANNOTATION: + // TODO supported by PHP + case GENERIC: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + " getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "PHP"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add('{'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + Set characterSet = new HashSet<>(); + characterSet.add('}'); + return characterSet; + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PythonLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PythonLanguage.java index b5e8539a..fadf4e50 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PythonLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/PythonLanguage.java @@ -1,30 +1,18 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author AmrDeveloper * @author M M Arif */ -public class PythonLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile( - "\\b(False|await|else|import|pass|None|break|except|in|raise" - + "|True|class|finally|is|return|and|continue|for|lambda" - + "|try|as|def|from|nonlocal|while|assert|del|global|not" - + "|with|async|elif|if|or|yield)\\b"); +public class PythonLanguage extends Language { // Brackets and Colons private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]"); @@ -34,70 +22,14 @@ public class PythonLanguage { private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); - private static final Pattern PATTERN_TODO_COMMENT = Pattern.compile("#TODO[^\n]*"); + private static final Pattern PATTERN_TODO_COMMENT = + Pattern.compile("#\\s?(TODO|todo)\\s[^\n]*"); private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); private static final Pattern PATTERN_OPERATION = Pattern.compile( ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); private static final Pattern PATTERN_HASH_COMMENT = Pattern.compile("#(?!TODO )[^\\n]*"); - - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_HASH_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.addSyntaxPattern(PATTERN_TODO_COMMENT, resources.getColor(R.color.gold, null)); - - codeView.reHighlightSyntax(); - } - - public static String[] getKeywords(Context context) { - return context.getResources().getStringArray(R.array.python_keywords); - } - - public static List getCodeList(Context context) { - List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); - for (String keyword : keywords) { - codeList.add(new Keyword(keyword)); - } - return codeList; - } - - public static Set getIndentationStarts() { - Set characterSet = new HashSet<>(); - characterSet.add(':'); - return characterSet; - } - - public static Set getIndentationEnds() { - return new HashSet<>(); - } + private static final Pattern PATTERN_ANNOTATION = Pattern.compile("@.[a-zA-Z0-9_]+"); public static String getCommentStart() { return "#"; @@ -106,4 +38,105 @@ public class PythonLanguage { public static String getCommentEnd() { return ""; } + + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + return PATTERN_HASH_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case TODO_COMMENT: + return PATTERN_TODO_COMMENT; + case ANNOTATION: + return PATTERN_ANNOTATION; + + case GENERIC: + case MULTI_LINE_COMMENT: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + "False", + "await", + "else", + "import", + "pass", + "None", + "break", + "except", + "in", + "raise", + "True", + "class", + "finally", + "is", + "return", + "and", + "continue", + "for", + "lambda", + "try", + "as", + "def", + "from", + "nonlocal", + "while", + "assert", + "del", + "global", + "not", + "with", + "async", + "elif", + "if", + "or", + "yield", + }; + } + + @Override + public List getCodeList() { + List codeList = new ArrayList<>(); + String[] keywords = getKeywords(); + for (String keyword : keywords) { + codeList.add(new Keyword(keyword)); + } + return codeList; + } + + @Override + public String getName() { + return "Python"; + } + + @Override + public Set getIndentationStarts() { + Set characterSet = new HashSet<>(); + characterSet.add(':'); + return characterSet; + } + + @Override + public Set getIndentationEnds() { + return new HashSet<>(); + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/TypeScriptLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/TypeScriptLanguage.java new file mode 100644 index 00000000..db458d03 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/TypeScriptLanguage.java @@ -0,0 +1,21 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +/** + * @author qwerty287 + */ +public class TypeScriptLanguage extends JavaScriptLanguage { + @Override + public String[] getKeywords() { + String[] js = super.getKeywords(); + String[] tsAdditions = {"declare", "module"}; + String[] ts = new String[js.length + tsAdditions.length]; + System.arraycopy(js, 0, ts, 0, js.length); + System.arraycopy(tsAdditions, 0, ts, js.length, tsAdditions.length); + return ts; + } + + @Override + public String getName() { + return "TypeScript"; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/UnknownLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/UnknownLanguage.java new file mode 100644 index 00000000..e22fdf1b --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/UnknownLanguage.java @@ -0,0 +1,43 @@ +package org.mian.gitnex.helpers.codeeditor.languages; + +import com.amrdeveloper.codeview.Code; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author qwerty287 + */ +public class UnknownLanguage extends Language { + + @Override + public Pattern getPattern(LanguageElement element) { + return null; + } + + @Override + public Set getIndentationStarts() { + return Set.of(); + } + + @Override + public Set getIndentationEnds() { + return Set.of(); + } + + @Override + public String[] getKeywords() { + return new String[0]; + } + + @Override + public List getCodeList() { + return new ArrayList<>(); + } + + @Override + public String getName() { + return "Unknown"; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/XmlLanguage.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/XmlLanguage.java index a3e7bbaf..a0d4cc89 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/XmlLanguage.java +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/languages/XmlLanguage.java @@ -1,25 +1,17 @@ package org.mian.gitnex.helpers.codeeditor.languages; -import android.content.Context; -import android.content.res.Resources; import com.amrdeveloper.codeview.Code; -import com.amrdeveloper.codeview.CodeView; import com.amrdeveloper.codeview.Keyword; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.mian.gitnex.R; /** * @author M M Arif */ -public class XmlLanguage { - - // Language Keywords - private static final Pattern PATTERN_KEYWORDS = - Pattern.compile("\\b(]{}()]"); @@ -29,79 +21,83 @@ public class XmlLanguage { private static final Pattern PATTERN_CHAR = Pattern.compile("['](.*?)[']"); private static final Pattern PATTERN_STRING = Pattern.compile("[\"](.*?)[\"]"); private static final Pattern PATTERN_HEX = Pattern.compile("0x[0-9a-fA-F]+"); - private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile("//[^\\n]*"); - private static final Pattern PATTERN_MULTI_LINE_COMMENT = - Pattern.compile("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"); + private static final Pattern PATTERN_SINGLE_LINE_COMMENT = Pattern.compile(""); private static final Pattern PATTERN_ATTRIBUTE = Pattern.compile("\\.[a-zA-Z0-9_]+"); private static final Pattern PATTERN_OPERATION = Pattern.compile( ":|==|>|<|!=|>=|<=|->|=|>|<|%|-|-=|%=|\\+|\\-|\\-=|\\+=|\\^|\\&|\\|::|\\?|\\*"); - public static void applyFiveColorsDarkTheme(Context context, CodeView codeView) { - codeView.resetSyntaxPatternList(); - codeView.resetHighlighter(); - - Resources resources = context.getResources(); - - // View Background - codeView.setBackgroundColor(resources.getColor(R.color.five_dark_black, null)); - - // Syntax Colors - codeView.addSyntaxPattern(PATTERN_HEX, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern(PATTERN_CHAR, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_STRING, resources.getColor(R.color.five_dark_yellow, null)); - codeView.addSyntaxPattern( - PATTERN_NUMBERS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_KEYWORDS, resources.getColor(R.color.five_dark_purple, null)); - codeView.addSyntaxPattern( - PATTERN_BUILTINS, resources.getColor(R.color.five_dark_white, null)); - codeView.addSyntaxPattern( - PATTERN_SINGLE_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_MULTI_LINE_COMMENT, resources.getColor(R.color.five_dark_grey, null)); - codeView.addSyntaxPattern( - PATTERN_ATTRIBUTE, resources.getColor(R.color.five_dark_blue, null)); - codeView.addSyntaxPattern( - PATTERN_OPERATION, resources.getColor(R.color.five_dark_purple, null)); - - // Default Color - codeView.setTextColor(resources.getColor(R.color.five_dark_white, null)); - - codeView.reHighlightSyntax(); + public static String getCommentStart() { + return ""; } - public static List getCodeList(Context context) { + @Override + public Pattern getPattern(LanguageElement element) { + switch (element) { + case KEYWORD: + return Pattern.compile("\\b(" + String.join("|", getKeywords()) + ")\\b"); + case BUILTIN: + return PATTERN_BUILTINS; + case NUMBER: + return PATTERN_NUMBERS; + case CHAR: + return PATTERN_CHAR; + case STRING: + return PATTERN_STRING; + case HEX: + return PATTERN_HEX; + case SINGLE_LINE_COMMENT: + case MULTI_LINE_COMMENT: + return PATTERN_SINGLE_LINE_COMMENT; + case ATTRIBUTE: + return PATTERN_ATTRIBUTE; + case OPERATION: + return PATTERN_OPERATION; + case GENERIC: + case TODO_COMMENT: + case ANNOTATION: + default: + return null; + } + } + + @Override + public String[] getKeywords() { + return new String[] { + " getCodeList() { List codeList = new ArrayList<>(); - String[] keywords = getKeywords(context); + String[] keywords = getKeywords(); for (String keyword : keywords) { codeList.add(new Keyword(keyword)); } return codeList; } - public static Set getIndentationStarts() { + @Override + public String getName() { + return "XML"; + } + + @Override + public Set getIndentationStarts() { Set characterSet = new HashSet<>(); characterSet.add('{'); return characterSet; } - public static Set getIndentationEnds() { + @Override + public Set getIndentationEnds() { Set characterSet = new HashSet<>(); characterSet.add('}'); return characterSet; } - - public static String getCommentStart() { - return "//"; - } - - public static String getCommentEnd() { - return ""; - } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/MarkwonHighlighter.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/MarkwonHighlighter.java new file mode 100644 index 00000000..ec2eccac --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/MarkwonHighlighter.java @@ -0,0 +1,47 @@ +package org.mian.gitnex.helpers.codeeditor.markwon; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; + +/** + * @author qwerty287 + */ +public class MarkwonHighlighter extends AbstractMarkwonPlugin { + + private final Theme theme; + private final Context context; + private final String fallbackLanguage; + + public MarkwonHighlighter( + Context context, @NonNull Theme theme, @Nullable String fallbackLanguage) { + this.theme = theme; + this.context = context; + this.fallbackLanguage = fallbackLanguage; + } + + @NonNull public static MarkwonHighlighter create(Context context, @NonNull Theme theme) { + return create(context, theme, null); + } + + @NonNull public static MarkwonHighlighter create( + Context context, @NonNull Theme theme, @Nullable String fallbackLanguage) { + return new MarkwonHighlighter(context, theme, fallbackLanguage); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.codeTextColor(context.getResources().getColor(theme.getDefaultColor(), null)) + .codeBackgroundColor( + context.getResources().getColor(theme.getBackgroundColor(), null)); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.syntaxHighlight(SyntaxHighlighter.create(context, theme, fallbackLanguage)); + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/SyntaxHighlighter.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/SyntaxHighlighter.java new file mode 100644 index 00000000..4061f1b2 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/markwon/SyntaxHighlighter.java @@ -0,0 +1,77 @@ +package org.mian.gitnex.helpers.codeeditor.markwon; + +import android.content.Context; +import android.text.Editable; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import io.noties.markwon.syntax.SyntaxHighlight; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.mian.gitnex.core.MainGrammarLocator; +import org.mian.gitnex.helpers.codeeditor.languages.Language; +import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; + +/** + * @author qwerty287 + */ +public class SyntaxHighlighter implements SyntaxHighlight { + + private final Theme theme; + private final Context context; + private final String fallback; + + protected SyntaxHighlighter(Context context, @NonNull Theme theme, @Nullable String fallback) { + this.context = context; + this.theme = theme; + this.fallback = fallback; + } + + @NonNull public static SyntaxHighlighter create(Context context, @NonNull Theme theme) { + return new SyntaxHighlighter(context, theme, null); + } + + @NonNull public static SyntaxHighlighter create( + Context context, @NonNull Theme theme, @Nullable String fallback) { + return new SyntaxHighlighter(context, theme, fallback); + } + + @NonNull @Override + public CharSequence highlight(@Nullable String info, @NonNull String code) { + if (code.isEmpty()) { + return code; + } + + if (info == null) { + info = fallback; + } + + if (info != null) { + info = MainGrammarLocator.fromExtension(info); + } + + Editable highlightedCode = new SpannableStringBuilder(code); + + Language l = Language.fromName(info); + + for (LanguageElement e : Objects.requireNonNull(LanguageElement.class.getEnumConstants())) { + Pattern p = l.getPattern(e); + if (p != null) { + Matcher matcher = p.matcher(highlightedCode); + while (matcher.find()) { + highlightedCode.setSpan( + new ForegroundColorSpan( + context.getResources().getColor(theme.getColor(e), null)), + matcher.start(), + matcher.end(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + } + return highlightedCode; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsDarkTheme.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsDarkTheme.java new file mode 100644 index 00000000..769d5be4 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsDarkTheme.java @@ -0,0 +1,51 @@ +package org.mian.gitnex.helpers.codeeditor.theme; + +import androidx.annotation.ColorRes; +import org.mian.gitnex.R; +import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement; + +/** + * @author qwerty287 + * @author M M Arif + */ +public class FiveColorsDarkTheme implements Theme { + + @Override + @ColorRes + public int getColor(LanguageElement element) { + switch (element) { + case HEX: + case NUMBER: + case KEYWORD: + case OPERATION: + case GENERIC: + return R.color.five_dark_purple; + case CHAR: + case STRING: + return R.color.five_dark_yellow; + case BUILTIN: + return R.color.five_dark_white; + case SINGLE_LINE_COMMENT: + case MULTI_LINE_COMMENT: + return R.color.five_dark_grey; + case ATTRIBUTE: + case TODO_COMMENT: + case ANNOTATION: + return R.color.five_dark_blue; + default: + return R.color.five_dark_white; + } + } + + @Override + @ColorRes + public int getDefaultColor() { + return R.color.five_dark_white; + } + + @Override + @ColorRes + public int getBackgroundColor() { + return R.color.five_dark_black; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsTheme.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsTheme.java new file mode 100644 index 00000000..43dd7ebd --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/FiveColorsTheme.java @@ -0,0 +1,51 @@ +package org.mian.gitnex.helpers.codeeditor.theme; + +import androidx.annotation.ColorRes; +import org.mian.gitnex.R; +import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement; + +/** + * @author qwerty287 + * @author M M Arif + */ +public class FiveColorsTheme implements Theme { + + @Override + @ColorRes + public int getColor(LanguageElement element) { + switch (element) { + case HEX: + case NUMBER: + case KEYWORD: + case OPERATION: + case GENERIC: + return R.color.five_dark_purple; + case CHAR: + case STRING: + return R.color.five_yellow; + case BUILTIN: + return R.color.five_dark_black; + case SINGLE_LINE_COMMENT: + case MULTI_LINE_COMMENT: + return R.color.five_dark_grey; + case ATTRIBUTE: + case TODO_COMMENT: + case ANNOTATION: + return R.color.five_dark_blue; + default: + return R.color.five_dark_black; + } + } + + @Override + @ColorRes + public int getDefaultColor() { + return R.color.five_dark_black; + } + + @Override + @ColorRes + public int getBackgroundColor() { + return R.color.five_background_grey; + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/Theme.java b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/Theme.java new file mode 100644 index 00000000..acaee35b --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/codeeditor/theme/Theme.java @@ -0,0 +1,32 @@ +package org.mian.gitnex.helpers.codeeditor.theme; + +import android.content.Context; +import androidx.annotation.ColorRes; +import org.mian.gitnex.R; +import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.codeeditor.languages.LanguageElement; + +/** + * @author qwerty287 + */ +public interface Theme { + + FiveColorsTheme FIVE_COLORS = new FiveColorsTheme(); + + FiveColorsDarkTheme FIVE_COLORS_DARK = new FiveColorsDarkTheme(); + + static Theme getDefaultTheme(Context context) { + return AppUtil.getColorFromAttribute(context, R.attr.isDark) == 1 + ? FIVE_COLORS_DARK + : FIVE_COLORS; + } + + @ColorRes + int getColor(LanguageElement element); + + @ColorRes + int getDefaultColor(); + + @ColorRes + int getBackgroundColor(); +} diff --git a/app/src/main/java/org/mian/gitnex/views/SyntaxHighlightedArea.java b/app/src/main/java/org/mian/gitnex/views/SyntaxHighlightedArea.java index b6be2e14..7350164a 100644 --- a/app/src/main/java/org/mian/gitnex/views/SyntaxHighlightedArea.java +++ b/app/src/main/java/org/mian/gitnex/views/SyntaxHighlightedArea.java @@ -16,21 +16,17 @@ import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import de.qwerty287.markwonprism4j.Prism4jSyntaxHighlight; -import de.qwerty287.markwonprism4j.Prism4jTheme; -import de.qwerty287.markwonprism4j.Prism4jThemeDarkula; -import de.qwerty287.markwonprism4j.Prism4jThemeDefault; -import io.noties.prism4j.Prism4j; -import org.mian.gitnex.R; import org.mian.gitnex.core.MainGrammarLocator; import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.codeeditor.markwon.SyntaxHighlighter; +import org.mian.gitnex.helpers.codeeditor.theme.Theme; /** * @author opyale */ public class SyntaxHighlightedArea extends LinearLayout { - private Prism4jTheme prism4jTheme; + private Theme theme; private TextView sourceView; private LinesView linesView; @@ -53,10 +49,7 @@ public class SyntaxHighlightedArea extends LinearLayout { public void setup() { - prism4jTheme = - AppUtil.getColorFromAttribute(getContext(), R.attr.isDark) == 1 - ? Prism4jThemeDarkula.create() - : Prism4jThemeDefault.create(); + theme = Theme.getDefaultTheme(getContext()); sourceView = new TextView(getContext()); @@ -67,7 +60,8 @@ public class SyntaxHighlightedArea extends LinearLayout { Typeface.createFromAsset( getContext().getAssets(), "fonts/sourcecodeproregular.ttf")); sourceView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); - sourceView.setTextColor(prism4jTheme.textColor()); + sourceView.setTextColor( + getContext().getResources().getColor(theme.getDefaultColor(), null)); sourceView.setTextIsSelectable(true); int padding = AppUtil.getPixelsFromDensity(getContext(), 5); @@ -93,12 +87,13 @@ public class SyntaxHighlightedArea extends LinearLayout { linesView.getPaint().setTypeface(sourceView.getTypeface()); linesView.getPaint().setTextSize(sourceView.getTextSize()); - linesView.setBackgroundColor(prism4jTheme.background()); - linesView.setTextColor(prism4jTheme.textColor()); - linesView.setLineColor(prism4jTheme.textColor()); + linesView.setBackgroundColor( + getContext().getResources().getColor(theme.getBackgroundColor(), null)); + linesView.setTextColor(getContext().getResources().getColor(theme.getDefaultColor(), null)); + linesView.setLineColor(getContext().getResources().getColor(theme.getDefaultColor(), null)); setOrientation(HORIZONTAL); - setBackgroundColor(prism4jTheme.background()); + setBackgroundColor(getContext().getResources().getColor(theme.getBackgroundColor(), null)); addView(linesView); addView(horizontalScrollView); } @@ -112,18 +107,16 @@ public class SyntaxHighlightedArea extends LinearLayout { () -> { try { - MainGrammarLocator mainGrammarLocator = - MainGrammarLocator.getInstance(); - CharSequence highlightedSource = - Prism4jSyntaxHighlight.create( - new Prism4j(mainGrammarLocator), - prism4jTheme, + SyntaxHighlighter.create( + getContext(), + theme, MainGrammarLocator .DEFAULT_FALLBACK_LANGUAGE) .highlight( - mainGrammarLocator.fromExtension( - extension), + MainGrammarLocator.fromExtension( + extension) + .toUpperCase(), source); getActivity() diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9ef28882..ca8c47b2 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -74,4 +74,6 @@ #a9b1ae #ffffff #e6b121 + #fdc92f + #f5f2f0 diff --git a/app/src/main/res/values/languages.xml b/app/src/main/res/values/languages.xml deleted file mode 100644 index a181d6ba..00000000 --- a/app/src/main/res/values/languages.xml +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - code - strong - small - template - form - input - textarea - button - option - label - fieldset - legend - datalist - frame - map - area - canvas - picture - svg - audio - source - track - video - link - nav - ul - ol - li - table - caption - th - tr - td - thead - tbody - tfooter - col - span - main - article - aside - meta - base - noscript - object - param - src - href - - - - - - encoding - version - - - - - - __construct - var_dump - define - echo - var - float - int - bool - false - true - function - private - public - protected - interface - return - copy - struct - abstract - extends - trait - static - namespace - implements - __set - __get - unlink - this - try - catch - Throwable - Exception - pdo - throw - new - and - or - if - else - elseif - switch - case - default - match - require - include - require_once - include_once - goto - do - while - for - foreach - map - hash - array - range - break - continue - preg_match - preg_match_all - preg_replace - str_replace - form - date - abs - min - max - strtotime - mktime - - - - - public - private - protected - package - abstract - boolean - break - byte - case - catch - char - class - continue - default - do - double - else - enum - extends - final - finally - float - for - if - implements - import - instanceof - int - interface - long - native - new - return - short - static - strictfp - super - switch - synchronized - this - throw - transient - try - void - volatile - while - - - - - break - default - func - interface - select - case - defer - go - map - struct - chan - else - goto - package - switch - const - fallthrough - if - bool - byte - cap - close - complex - complex64 - complex128 - uint16 - copy - false - float32 - float64 - imag - int - int8 - int16 - uint32 - int32 - int64 - len - make - new - nil - uint64 - range - type - continue - for - import - return - var - - - - - False - await - else - import - pass - None - break - except - in - raise - True - class - finally - is - return - and - continue - for - lambda - try - as - def - from - nonlocal - while - assert - del - global - not - with - async - elif - if - or - yield - - - From 07e048e29f2a006b6fd401b7b48e5af76b6ce252 Mon Sep 17 00:00:00 2001 From: M M Arif Date: Sat, 1 Oct 2022 06:16:19 +0200 Subject: [PATCH 2/2] [App Only] Notes (#1207) Closes #656 It is a simple notes feature where you can add your notes related to your repos, issues etc etc. For me I sometime came across an issue or thing to fix/add but away from PC. I have notes app, but there are so many things in it and sometime it is lost where I save it. So this will be an easy way to remind me of it when needed. It can be used as a generic Notes app too. Co-authored-by: M M Arif Co-authored-by: qwerty287 Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1207 Reviewed-by: qwerty287 --- app/build.gradle | 6 +- app/src/main/AndroidManifest.xml | 4 + .../gitnex/activities/CreateNoteActivity.java | 182 ++++++++++++++++ .../activities/IssueDetailActivity.java | 45 ++-- .../mian/gitnex/activities/MainActivity.java | 18 ++ .../SettingsAppearanceActivity.java | 41 ---- .../activities/SettingsGeneralActivity.java | 3 + .../mian/gitnex/activities/WikiActivity.java | 2 +- .../adapters/AdminCronTasksAdapter.java | 12 +- .../gitnex/adapters/AdminGetUsersAdapter.java | 1 - .../mian/gitnex/adapters/CommitsAdapter.java | 10 +- .../gitnex/adapters/ExploreIssuesAdapter.java | 49 +---- .../adapters/ExploreRepositoriesAdapter.java | 58 +---- .../gitnex/adapters/IssueCommentsAdapter.java | 40 ++-- .../mian/gitnex/adapters/IssuesAdapter.java | 49 +---- .../gitnex/adapters/MilestonesAdapter.java | 45 ++-- .../mian/gitnex/adapters/NotesAdapter.java | 152 +++++++++++++ .../gitnex/adapters/PullRequestsAdapter.java | 17 +- .../mian/gitnex/adapters/ReleasesAdapter.java | 18 +- .../gitnex/adapters/RepoForksAdapter.java | 57 +---- .../gitnex/adapters/ReposListAdapter.java | 54 +---- .../mian/gitnex/adapters/WikiListAdapter.java | 32 ++- .../org/mian/gitnex/core/MainApplication.java | 41 ++-- .../mian/gitnex/database/api/NotesApi.java | 61 ++++++ .../mian/gitnex/database/dao/NotesDao.java | 36 +++ .../gitnex/database/db/GitnexDatabase.java | 20 +- .../mian/gitnex/database/models/Notes.java | 52 +++++ .../fragments/CommitDetailFragment.java | 8 +- .../mian/gitnex/fragments/NotesFragment.java | 206 ++++++++++++++++++ .../gitnex/fragments/RepoInfoFragment.java | 22 +- .../fragments/profile/DetailFragment.java | 20 +- .../org/mian/gitnex/helpers/TimeHelper.java | 35 +-- app/src/main/res/drawable/ic_notes.xml | 34 +++ .../main/res/layout/activity_create_note.xml | 87 ++++++++ .../layout/activity_settings_appearance.xml | 33 --- .../res/layout/fragment_administration.xml | 62 +++--- app/src/main/res/layout/fragment_notes.xml | 62 ++++++ .../res/layout/list_most_visited_repos.xml | 2 +- app/src/main/res/layout/list_notes.xml | 82 +++++++ app/src/main/res/menu/drawer_menu.xml | 4 + app/src/main/res/values/settings.xml | 6 +- app/src/main/res/values/strings.xml | 17 +- 42 files changed, 1193 insertions(+), 592 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/activities/CreateNoteActivity.java create mode 100644 app/src/main/java/org/mian/gitnex/adapters/NotesAdapter.java create mode 100644 app/src/main/java/org/mian/gitnex/database/api/NotesApi.java create mode 100644 app/src/main/java/org/mian/gitnex/database/dao/NotesDao.java create mode 100644 app/src/main/java/org/mian/gitnex/database/models/Notes.java create mode 100644 app/src/main/java/org/mian/gitnex/fragments/NotesFragment.java create mode 100644 app/src/main/res/drawable/ic_notes.xml create mode 100644 app/src/main/res/layout/activity_create_note.xml create mode 100644 app/src/main/res/layout/fragment_notes.xml create mode 100644 app/src/main/res/layout/list_notes.xml diff --git a/app/build.gradle b/app/build.gradle index aabbedae..6d79b9d5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,10 +56,10 @@ dependencies { def lifecycle_version = '2.5.1' def markwon_version = '4.6.2' def work_version = "2.7.1" - def acra = '5.8.4' + def acra = '5.9.6' implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.appcompat:appcompat:1.5.0' + implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'com.google.android.material:material:1.6.1' implementation 'androidx.compose.material3:material3:1.0.0-alpha15' implementation 'androidx.compose.material3:material3-window-size-class:1.0.0-alpha15' @@ -71,7 +71,7 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2' - implementation "com.google.code.gson:gson:2.9.0" + implementation 'com.google.code.gson:gson:2.9.1' implementation "com.squareup.picasso:picasso:2.71828" implementation 'jp.wasabeef:picasso-transformations:2.4.0' implementation 'jp.co.cyberagent.android:gpuimage:2.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cf005e48..deb90e81 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -169,6 +169,10 @@ android:name=".activities.CodeEditorActivity" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation" android:windowSoftInputMode="adjustResize"/> + finish()); + + if (getIntent().getStringExtra("action") != null) { + action = getIntent().getStringExtra("action"); + } else { + action = ""; + } + + binding.close.setOnClickListener(close -> finish()); + binding.toolbarTitle.setMovementMethod(new ScrollingMovementMethod()); + + if (action.equalsIgnoreCase("edit")) { + + noteId = getIntent().getIntExtra("noteId", 0); + notes = notesApi.fetchNoteById(noteId); + binding.noteContent.setText(notes.getContent()); + + binding.markdownPreview.setVisibility(View.GONE); + binding.toolbarTitle.setText(R.string.editNote); + + binding.noteContent.addTextChangedListener( + new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) { + + String text = binding.noteContent.getText().toString(); + + if (!text.isEmpty()) { + + updateNote(text); + } + } + + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged( + CharSequence s, int start, int before, int count) {} + }); + } else if (action.equalsIgnoreCase("add")) { + + binding.markdownPreview.setVisibility(View.GONE); + + binding.noteContent.addTextChangedListener( + new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) { + + String text = binding.noteContent.getText().toString(); + + if (!text.isEmpty() && text.length() > 4) { + + if (noteId > 0) { + updateNote(text); + } else { + noteId = + (int) + notesApi.insertNote( + text, + (int) Instant.now().getEpochSecond()); + } + } + } + + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged( + CharSequence s, int start, int before, int count) {} + }); + } else { + binding.markdownPreview.setVisibility(View.VISIBLE); + } + } + + private void updateNote(String content) { + notesApi.updateNote(content, Instant.now().getEpochSecond(), noteId); + } + + @Override + public boolean onCreateOptionsMenu(@NonNull Menu menu) { + + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.markdown_switcher, menu); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + int id = item.getItemId(); + + if (id == android.R.id.home) { + + finish(); + return true; + } else if (id == R.id.markdown) { + + if (action.equalsIgnoreCase("edit") || action.equalsIgnoreCase("add")) { + if (!renderMd) { + Markdown.render( + ctx, + EmojiParser.parseToUnicode( + Objects.requireNonNull( + binding.noteContent.getText().toString())), + binding.markdownPreview); + + binding.markdownPreview.setVisibility(View.VISIBLE); + binding.noteContent.setVisibility(View.GONE); + renderMd = true; + } else { + binding.markdownPreview.setVisibility(View.GONE); + binding.noteContent.setVisibility(View.VISIBLE); + renderMd = false; + } + } + + return true; + } else { + return super.onOptionsItemSelected(item); + } + } +} diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java index 3c65beb7..88d4fce6 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -67,7 +67,6 @@ import org.mian.gitnex.helpers.LabelWidthCalculator; import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.structs.BottomSheetListener; @@ -774,9 +773,7 @@ public class IssueDetailActivity extends BaseActivity } } - TinyDB tinyDb = TinyDB.getInstance(appCtx); final Locale locale = getResources().getConfiguration().locale; - final String timeFormat = tinyDb.getString("dateFormat", "pretty"); issueCreator = issue.getIssue().getUser().getLogin(); PicassoService.getInstance(ctx) @@ -945,22 +942,14 @@ public class IssueDetailActivity extends BaseActivity if (issue.getIssue().getDueDate() != null) { viewBinding.dueDateFrame.setVisibility(View.VISIBLE); - if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { - - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", locale); - String dueDate = formatter.format(issue.getIssue().getDueDate()); - viewBinding.issueDueDate.setText(dueDate); - viewBinding.issueDueDate.setOnClickListener( - new ClickListener( - TimeHelper.customDateFormatForToastDateFormat( - issue.getIssue().getDueDate()), - ctx)); - } else if (timeFormat.equals("normal1")) { - - DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", locale); - String dueDate = formatter.format(issue.getIssue().getDueDate()); - viewBinding.issueDueDate.setText(dueDate); - } + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", locale); + String dueDate = formatter.format(issue.getIssue().getDueDate()); + viewBinding.issueDueDate.setText(dueDate); + viewBinding.issueDueDate.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat( + issue.getIssue().getDueDate()), + ctx)); } else { viewBinding.dueDateFrame.setVisibility(View.GONE); @@ -983,18 +972,14 @@ public class IssueDetailActivity extends BaseActivity viewBinding.issueModified.setVisibility(View.INVISIBLE); } - viewBinding.issueCreatedTime.setText( - TimeHelper.formatTime(issue.getIssue().getCreatedAt(), locale, timeFormat, ctx)); viewBinding.issueCreatedTime.setVisibility(View.VISIBLE); - - if (timeFormat.equals("pretty")) { - - viewBinding.issueCreatedTime.setOnClickListener( - new ClickListener( - TimeHelper.customDateFormatForToastDateFormat( - issue.getIssue().getCreatedAt()), - ctx)); - } + viewBinding.issueCreatedTime.setText( + TimeHelper.formatTime(issue.getIssue().getCreatedAt(), locale)); + viewBinding.issueCreatedTime.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat( + issue.getIssue().getCreatedAt()), + ctx)); Bundle bundle = new Bundle(); bundle.putString("repoOwner", repoOwner); diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java index 4b934554..6ba5cd85 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -46,6 +46,7 @@ import org.mian.gitnex.fragments.MostVisitedReposFragment; import org.mian.gitnex.fragments.MyIssuesFragment; import org.mian.gitnex.fragments.MyProfileFragment; import org.mian.gitnex.fragments.MyRepositoriesFragment; +import org.mian.gitnex.fragments.NotesFragment; import org.mian.gitnex.fragments.NotificationsFragment; import org.mian.gitnex.fragments.OrganizationsFragment; import org.mian.gitnex.fragments.RepositoriesFragment; @@ -143,6 +144,8 @@ public class MainActivity extends BaseActivity toolbarTitle.setText(getResources().getString(R.string.navProfile)); } else if (fragmentById instanceof MostVisitedReposFragment) { toolbarTitle.setText(getResources().getString(R.string.navMostVisited)); + } else if (fragmentById instanceof NotesFragment) { + toolbarTitle.setText(getResources().getString(R.string.navNotes)); } else if (fragmentById instanceof DraftsFragment) { toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); } else if (fragmentById instanceof AdministrationFragment) { @@ -490,6 +493,14 @@ public class MainActivity extends BaseActivity .commit(); navigationView.setCheckedItem(R.id.nav_most_visited); break; + case 10: + toolbarTitle.setText(getResources().getString(R.string.navNotes)); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, new NotesFragment()) + .commit(); + navigationView.setCheckedItem(R.id.nav_notes); + break; default: toolbarTitle.setText(getResources().getString(R.string.navMyRepos)); @@ -708,6 +719,13 @@ public class MainActivity extends BaseActivity .beginTransaction() .replace(R.id.fragment_container, new MostVisitedReposFragment()) .commit(); + } else if (id == R.id.nav_notes) { + + toolbarTitle.setText(getResources().getString(R.string.navNotes)); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, new NotesFragment()) + .commit(); } drawer.closeDrawer(GravityCompat.START); diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java index 7580fb47..14714352 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java @@ -24,8 +24,6 @@ import org.mian.gitnex.helpers.Toasty; */ public class SettingsAppearanceActivity extends BaseActivity { - private static String[] timeList; - private static int timeSelectedChoice = 0; private static String[] customFontList; private static int customFontSelectedChoice = 0; private static String[] themeList; @@ -43,7 +41,6 @@ public class SettingsAppearanceActivity extends BaseActivity { ImageView closeActivity = activitySettingsAppearanceBinding.close; - LinearLayout timeFrame = activitySettingsAppearanceBinding.timeFrame; LinearLayout customFontFrame = activitySettingsAppearanceBinding.customFontFrame; LinearLayout themeFrame = activitySettingsAppearanceBinding.themeSelectionFrame; LinearLayout lightTimeFrame = @@ -52,7 +49,6 @@ public class SettingsAppearanceActivity extends BaseActivity { SwitchMaterial counterBadgesSwitch = activitySettingsAppearanceBinding.switchCounterBadge; - timeList = getResources().getStringArray(R.array.timeFormats); customFontList = getResources().getStringArray(R.array.fonts); themeList = getResources().getStringArray(R.array.themes); @@ -77,7 +73,6 @@ public class SettingsAppearanceActivity extends BaseActivity { darkHour = "0" + darkHour; } - timeSelectedChoice = tinyDB.getInt("timeId"); customFontSelectedChoice = tinyDB.getInt("customFontId", 1); themeSelectedChoice = tinyDB.getInt("themeId", 6); // use system theme as default @@ -87,7 +82,6 @@ public class SettingsAppearanceActivity extends BaseActivity { activitySettingsAppearanceBinding.darkThemeSelectedTime.setText( ctx.getResources() .getString(R.string.settingsThemeTimeSelectedHint, darkHour, darkMinute)); - activitySettingsAppearanceBinding.tvDateTimeSelected.setText(timeList[timeSelectedChoice]); activitySettingsAppearanceBinding.customFontSelected.setText( customFontList[customFontSelectedChoice]); activitySettingsAppearanceBinding.themeSelected.setText(themeList[themeSelectedChoice]); @@ -196,41 +190,6 @@ public class SettingsAppearanceActivity extends BaseActivity { materialAlertDialogBuilder.create().show(); }); - - // time and date dialog - timeFrame.setOnClickListener( - view -> { - MaterialAlertDialogBuilder materialAlertDialogBuilder = - new MaterialAlertDialogBuilder(ctx) - .setTitle(R.string.settingsTimeSelectorDialogTitle) - .setCancelable(timeSelectedChoice != -1) - .setSingleChoiceItems( - timeList, - timeSelectedChoice, - (dialogInterfaceTime, i) -> { - timeSelectedChoice = i; - activitySettingsAppearanceBinding.tvDateTimeSelected - .setText(timeList[i]); - tinyDB.putInt("timeId", i); - - switch (i) { - case 0: - tinyDB.putString("dateFormat", "pretty"); - break; - case 1: - tinyDB.putString("dateFormat", "normal"); - break; - } - - dialogInterfaceTime.dismiss(); - Toasty.success( - appCtx, - getResources() - .getString(R.string.settingsSave)); - }); - - materialAlertDialogBuilder.create().show(); - }); } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java index b86f11d4..1c99b114 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java @@ -90,6 +90,9 @@ public class SettingsGeneralActivity extends BaseActivity { viewBinding.homeScreenSelected.setText( getResources().getString(R.string.navMostVisited)); + } else if (homeScreenSelectedChoice == 10) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.navNotes)); } viewBinding.homeScreenFrame.setOnClickListener( diff --git a/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java b/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java index f7109966..b9542393 100644 --- a/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java @@ -395,7 +395,7 @@ public class WikiActivity extends BaseActivity implements BottomSheetListener { } @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(@NonNull Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.markdown_switcher, menu); diff --git a/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java index aee87bcd..72e605aa 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java @@ -18,7 +18,6 @@ import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import retrofit2.Call; import retrofit2.Callback; @@ -43,7 +42,6 @@ public class AdminCronTasksAdapter Context ctx = itemView.getContext(); final Locale locale = ctx.getResources().getConfiguration().locale; - final String timeFormat = TinyDB.getInstance(ctx).getString("dateFormat", "pretty"); ImageView runTask = itemView.findViewById(R.id.runTask); taskName = itemView.findViewById(R.id.taskName); @@ -56,14 +54,10 @@ public class AdminCronTasksAdapter String lastRun = ""; if (cronTasks.getNext() != null) { - nextRun = - TimeHelper.formatTime( - cronTasks.getNext(), locale, timeFormat, ctx); + nextRun = TimeHelper.formatTime(cronTasks.getNext(), locale); } if (cronTasks.getPrev() != null) { - lastRun = - TimeHelper.formatTime( - cronTasks.getPrev(), locale, timeFormat, ctx); + lastRun = TimeHelper.formatTime(cronTasks.getPrev(), locale); } View view = @@ -127,7 +121,7 @@ public class AdminCronTasksAdapter Call call = RetrofitClient.getApiInterface(ctx).adminCronRun(taskName); call.enqueue( - new Callback() { + new Callback<>() { @Override public void onResponse( diff --git a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java index 731a0b86..a4c2ff77 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java @@ -135,7 +135,6 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter - TimeHelper.customDateFormatForToastDateFormat( - issueComment.getCreatedAt())); - } else if (timeFormat.equals("normal")) { - infoBuilder = - new StringBuilder( - TimeHelper.formatTime( - issueComment.getCreatedAt(), - locale, - "normal", - context)); - } + infoBuilder = + new StringBuilder( + TimeHelper.formatTime(issueComment.getCreatedAt(), locale)); + + information.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat( + issueComment.getCreatedAt()), + context)); if (!issueComment.getCreatedAt().equals(issueComment.getUpdatedAt())) { - if (infoBuilder != null) { - infoBuilder - .append(context.getString(R.string.colorfulBulletSpan)) - .append(context.getString(R.string.modifiedText)); - } + infoBuilder + .append(context.getString(R.string.colorfulBulletSpan)) + .append(context.getString(R.string.modifiedText)); } } String info = infoBuilder.toString(); diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java index e0902080..15febc26 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java @@ -21,8 +21,6 @@ import androidx.core.text.HtmlCompat; import androidx.recyclerview.widget.RecyclerView; import com.amulyakhare.textdrawable.TextDrawable; import com.vdurmont.emoji.EmojiParser; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; import org.gitnex.tea4j.v2.models.Issue; @@ -39,7 +37,6 @@ import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.contexts.IssueContext; -import org.ocpsoft.prettytime.PrettyTime; /** * @author M M Arif @@ -169,7 +166,6 @@ public class IssuesAdapter extends RecyclerView.Adapter void bindData(Issue issue) { Locale locale = context.getResources().getConfiguration().locale; - String timeFormat = tinyDb.getString("dateFormat", "pretty"); int imgRadius = AppUtil.getPixelsFromDensity(context, 3); @@ -294,46 +290,11 @@ public class IssuesAdapter extends RecyclerView.Adapter context.getResources().getColor(R.color.releasePre, null)); } - switch (timeFormat) { - case "pretty": - { - PrettyTime prettyTime = new PrettyTime(locale); - String createdTime = prettyTime.format(issue.getCreatedAt()); - this.issueCreatedTime.setText(createdTime); - this.issueCreatedTime.setOnClickListener( - new ClickListener( - TimeHelper.customDateFormatForToastDateFormat( - issue.getCreatedAt()), - context)); - break; - } - case "normal": - { - DateFormat formatter = - new SimpleDateFormat( - "yyyy-MM-dd '" - + context.getResources() - .getString(R.string.timeAtText) - + "' HH:mm", - locale); - String createdTime = formatter.format(issue.getCreatedAt()); - this.issueCreatedTime.setText(createdTime); - break; - } - case "normal1": - { - DateFormat formatter = - new SimpleDateFormat( - "dd-MM-yyyy '" - + context.getResources() - .getString(R.string.timeAtText) - + "' HH:mm", - locale); - String createdTime = formatter.format(issue.getCreatedAt()); - this.issueCreatedTime.setText(createdTime); - break; - } - } + this.issueCreatedTime.setText(TimeHelper.formatTime(issue.getCreatedAt(), locale)); + this.issueCreatedTime.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat(issue.getCreatedAt()), + context)); } } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java index 9087246c..1cf19c05 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java @@ -25,7 +25,6 @@ import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.contexts.RepositoryContext; /** @@ -188,9 +187,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter { + + private List notesList; + private final Context ctx; + private final Intent noteIntent; + + public NotesAdapter(Context ctx, List notesListMain) { + this.ctx = ctx; + this.notesList = notesListMain; + noteIntent = new Intent(ctx, CreateNoteActivity.class); + } + + class NotesViewHolder extends RecyclerView.ViewHolder { + + private Notes notes; + + private final TextView content; + private final TextView datetime; + + private NotesViewHolder(View itemView) { + + super(itemView); + + content = itemView.findViewById(R.id.content); + datetime = itemView.findViewById(R.id.datetime); + ImageView deleteNote = itemView.findViewById(R.id.delete_note); + + itemView.setOnClickListener( + view -> { + noteIntent.putExtra("action", "edit"); + noteIntent.putExtra("noteId", notes.getNoteId()); + ctx.startActivity(noteIntent); + }); + + deleteNote.setOnClickListener( + itemDelete -> { + MaterialAlertDialogBuilder materialAlertDialogBuilder = + new MaterialAlertDialogBuilder( + ctx, R.style.ThemeOverlay_Material3_Dialog_Alert); + + materialAlertDialogBuilder + .setTitle(ctx.getString(R.string.menuDeleteText)) + .setMessage(ctx.getString(R.string.noteDeleteDialoMessage)) + .setPositiveButton( + R.string.menuDeleteText, + (dialog, whichButton) -> + deleteNote( + getBindingAdapterPosition(), + notes.getNoteId())) + .setNeutralButton(R.string.cancelButton, null) + .show(); + }); + } + } + + private void deleteNote(int position, int noteId) { + + NotesApi notesApi = BaseApi.getInstance(ctx, NotesApi.class); + assert notesApi != null; + notesApi.deleteNote(noteId); + notesList.remove(position); + notifyItemRemoved(position); + notifyItemRangeChanged(position, notesList.size()); + Toasty.success(ctx, ctx.getResources().getQuantityString(R.plurals.noteDeleteMessage, 1)); + } + + @NonNull @Override + public NotesAdapter.NotesViewHolder onCreateViewHolder( + @NonNull ViewGroup parent, int viewType) { + View v = + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.list_notes, parent, false); + return new NotesViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull NotesAdapter.NotesViewHolder holder, int position) { + + Locale locale = ctx.getResources().getConfiguration().locale; + Notes currentItem = notesList.get(position); + holder.notes = currentItem; + + Markdown.render( + ctx, + EmojiParser.parseToUnicode( + Objects.requireNonNull( + StringUtils.substring(currentItem.getContent(), 0, 140))), + holder.content); + + if (currentItem.getModified() != null) { + String modifiedTime = + TimeHelper.formatTime( + Date.from(Instant.ofEpochSecond(currentItem.getModified())), locale); + holder.datetime.setText( + ctx.getResources().getString(R.string.noteTimeModified, modifiedTime)); + } else { + String createdTime = + TimeHelper.formatTime( + Date.from(Instant.ofEpochSecond(currentItem.getDatetime())), locale); + holder.datetime.setText( + ctx.getResources().getString(R.string.noteDateTime, createdTime)); + } + } + + @Override + public int getItemCount() { + return notesList.size(); + } + + @SuppressLint("NotifyDataSetChanged") + public void notifyDataChanged() { + notifyDataSetChanged(); + } + + public void updateList(List list) { + + notesList = list; + notifyDataChanged(); + } +} diff --git a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java index 61cdefc7..516b334c 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java @@ -175,12 +175,10 @@ public class PullRequestsAdapter extends RecyclerView.Adapter 15) { commentIcon.setImageDrawable( @@ -299,13 +296,11 @@ public class PullRequestsAdapter extends RecyclerView.Adapter 0) { - String firstCharacter = String.valueOf(wikiPageMetaData.getTitle().charAt(0)); + String firstCharacter = String.valueOf(wikiPageMetaData.getTitle().charAt(0)); - TextDrawable drawable = - TextDrawable.builder() - .beginConfig() - .useFont(Typeface.DEFAULT) - .fontSize(18) - .toUpperCase() - .width(28) - .height(28) - .endConfig() - .buildRoundRect(firstCharacter, color, 14); - avatar.setImageDrawable(drawable); - } else { - avatar.setVisibility(View.GONE); - } + TextDrawable drawable = + TextDrawable.builder() + .beginConfig() + .useFont(Typeface.DEFAULT) + .fontSize(18) + .toUpperCase() + .width(28) + .height(28) + .endConfig() + .buildRoundRect(firstCharacter, color, 14); + avatar.setImageDrawable(drawable); if (!((RepoDetailActivity) ctx).repository.getPermissions().isPush()) { wikiMenu.setVisibility(View.GONE); diff --git a/app/src/main/java/org/mian/gitnex/core/MainApplication.java b/app/src/main/java/org/mian/gitnex/core/MainApplication.java index 9b70a466..1ec6e47c 100644 --- a/app/src/main/java/org/mian/gitnex/core/MainApplication.java +++ b/app/src/main/java/org/mian/gitnex/core/MainApplication.java @@ -52,7 +52,7 @@ public class MainApplication extends Application { if (tinyDB.getBoolean("crashReportingEnabled", true)) { - CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this); + CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(); ACRABuilder.withBuildConfigClass(BuildConfig.class) .withReportContent( @@ -62,23 +62,28 @@ public class MainApplication extends Application { ReportField.AVAILABLE_MEM_SIZE, ReportField.BRAND) .setReportFormat(StringFormat.KEY_VALUE_LIST); - ACRABuilder.getPluginConfigurationBuilder(NotificationConfigurationBuilder.class) - .withResTitle(R.string.crashTitle) - .withResIcon(R.drawable.gitnex_transparent) - .withResChannelName(R.string.setCrashReports) - .withResText(R.string.crashMessage) - .withEnabled(true); - ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class) - .withMailTo(getResources().getString(R.string.appEmail)) - .withSubject( - getResources() - .getString( - R.string.crashReportEmailSubject, - AppUtil.getAppBuildNo(context))) - .withReportAsFile(true) - .withEnabled(true); - ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class) - .setEnabled(true); + + ACRABuilder.withPluginConfigurations( + new NotificationConfigurationBuilder() + .withTitle(getString(R.string.crashTitle)) + .withResIcon(R.drawable.gitnex_transparent) + .withChannelName(getString(R.string.setCrashReports)) + .withText(getString(R.string.crashMessage)) + .build()); + + ACRABuilder.withPluginConfigurations( + new MailSenderConfigurationBuilder() + .withMailTo(getResources().getString(R.string.appEmail)) + .withSubject( + getResources() + .getString( + R.string.crashReportEmailSubject, + AppUtil.getAppBuildNo(context))) + .withReportAsFile(true) + .build()); + + ACRABuilder.withPluginConfigurations( + new LimiterConfigurationBuilder().withEnabled(true).build()); ACRA.init(this, ACRABuilder); } diff --git a/app/src/main/java/org/mian/gitnex/database/api/NotesApi.java b/app/src/main/java/org/mian/gitnex/database/api/NotesApi.java new file mode 100644 index 00000000..f6ad2046 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/database/api/NotesApi.java @@ -0,0 +1,61 @@ +package org.mian.gitnex.database.api; + +import android.content.Context; +import androidx.lifecycle.LiveData; +import java.util.List; +import org.mian.gitnex.database.dao.NotesDao; +import org.mian.gitnex.database.models.Notes; + +/** + * @author M M Arif + */ +public class NotesApi extends BaseApi { + + private final NotesDao notesDao; + + NotesApi(Context context) { + super(context); + notesDao = gitnexDatabase.notesDao(); + } + + public long insertNote(String content, Integer datetime) { + + Notes notes = new Notes(); + notes.setContent(content); + notes.setDatetime(datetime); + + return insertNoteAsyncTask(notes); + } + + public long insertNoteAsyncTask(Notes notes) { + return notesDao.insertNote(notes); + } + + public LiveData> fetchAllNotes() { + return notesDao.fetchAllNotes(); + } + + public Notes fetchNoteById(int noteId) { + return notesDao.fetchNoteById(noteId); + } + + public Integer fetchNotesCount() { + return notesDao.fetchNotesCount(); + } + + public void updateNote(final String content, final long modified, int noteId) { + executorService.execute(() -> notesDao.updateNote(content, modified, noteId)); + } + + public void deleteAllNotes() { + executorService.execute(notesDao::deleteAllNotes); + } + + public void deleteNote(final int noteId) { + final Notes note = notesDao.fetchNoteById(noteId); + + if (note != null) { + executorService.execute(() -> notesDao.deleteNote(noteId)); + } + } +} diff --git a/app/src/main/java/org/mian/gitnex/database/dao/NotesDao.java b/app/src/main/java/org/mian/gitnex/database/dao/NotesDao.java new file mode 100644 index 00000000..6433faa0 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/database/dao/NotesDao.java @@ -0,0 +1,36 @@ +package org.mian.gitnex.database.dao; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; +import java.util.List; +import org.mian.gitnex.database.models.Notes; + +/** + * @author M M Arif + */ +@Dao +public interface NotesDao { + + @Insert + long insertNote(Notes notes); + + @Query("SELECT * FROM Notes ORDER BY modified DESC, noteId DESC") + LiveData> fetchAllNotes(); + + @Query("SELECT * FROM Notes WHERE noteId = :noteId") + Notes fetchNoteById(int noteId); + + @Query("SELECT count(noteId) FROM Notes") + Integer fetchNotesCount(); + + @Query("UPDATE Notes SET content = :content, modified = :modified WHERE noteId = :noteId") + void updateNote(String content, long modified, int noteId); + + @Query("DELETE FROM Notes") + void deleteAllNotes(); + + @Query("DELETE FROM Notes WHERE noteId = :noteId") + void deleteNote(int noteId); +} diff --git a/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java b/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java index f0dd225f..cac62fd3 100644 --- a/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java +++ b/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java @@ -8,9 +8,11 @@ import androidx.room.RoomDatabase; import androidx.room.migration.Migration; import androidx.sqlite.db.SupportSQLiteDatabase; import org.mian.gitnex.database.dao.DraftsDao; +import org.mian.gitnex.database.dao.NotesDao; import org.mian.gitnex.database.dao.RepositoriesDao; import org.mian.gitnex.database.dao.UserAccountsDao; import org.mian.gitnex.database.models.Draft; +import org.mian.gitnex.database.models.Notes; import org.mian.gitnex.database.models.Repository; import org.mian.gitnex.database.models.UserAccount; @@ -18,8 +20,8 @@ import org.mian.gitnex.database.models.UserAccount; * @author M M Arif */ @Database( - entities = {Draft.class, Repository.class, UserAccount.class}, - version = 6, + entities = {Draft.class, Repository.class, UserAccount.class, Notes.class}, + version = 7, exportSchema = false) public abstract class GitnexDatabase extends RoomDatabase { @@ -68,6 +70,15 @@ public abstract class GitnexDatabase extends RoomDatabase { "ALTER TABLE 'Repositories' ADD COLUMN 'mostVisited' INTEGER NOT NULL DEFAULT 0"); } }; + private static final Migration MIGRATION_6_7 = + new Migration(6, 7) { + + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL( + "CREATE TABLE IF NOT EXISTS 'Notes' ('noteId' INTEGER NOT NULL, 'content' TEXT, 'datetime' INTEGER, 'modified' INTEGER, PRIMARY KEY('noteid'))"); + } + }; private static volatile GitnexDatabase gitnexDatabase; public static GitnexDatabase getDatabaseInstance(Context context) { @@ -85,7 +96,8 @@ public abstract class GitnexDatabase extends RoomDatabase { MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, - MIGRATION_5_6) + MIGRATION_5_6, + MIGRATION_6_7) .build(); } } @@ -99,4 +111,6 @@ public abstract class GitnexDatabase extends RoomDatabase { public abstract RepositoriesDao repositoriesDao(); public abstract UserAccountsDao userAccountsDao(); + + public abstract NotesDao notesDao(); } diff --git a/app/src/main/java/org/mian/gitnex/database/models/Notes.java b/app/src/main/java/org/mian/gitnex/database/models/Notes.java new file mode 100644 index 00000000..41f6e6ac --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/database/models/Notes.java @@ -0,0 +1,52 @@ +package org.mian.gitnex.database.models; + +import androidx.annotation.Nullable; +import androidx.room.Entity; +import androidx.room.PrimaryKey; +import java.io.Serializable; + +/** + * @author M M Arif + */ +@Entity(tableName = "Notes") +public class Notes implements Serializable { + + @PrimaryKey(autoGenerate = true) + private int noteId; + + @Nullable private String content; + private Integer datetime; + private Integer modified; + + public int getNoteId() { + return noteId; + } + + public void setNoteId(int noteId) { + this.noteId = noteId; + } + + @Nullable public String getContent() { + return content; + } + + public void setContent(@Nullable String content) { + this.content = content; + } + + public Integer getDatetime() { + return datetime; + } + + public void setDatetime(Integer datetime) { + this.datetime = datetime; + } + + public Integer getModified() { + return modified; + } + + public void setModified(Integer modified) { + this.modified = modified; + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/CommitDetailFragment.java b/app/src/main/java/org/mian/gitnex/fragments/CommitDetailFragment.java index c23073ea..9d4b3785 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/CommitDetailFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/CommitDetailFragment.java @@ -229,9 +229,7 @@ public class CommitDetailFragment extends Fragment { .getDate()), getResources() .getConfiguration() - .locale, - "pretty", - requireContext())), + .locale)), HtmlCompat.FROM_HTML_MODE_COMPACT)); } else { binding.commitAuthorAndCommitter.setText( @@ -250,9 +248,7 @@ public class CommitDetailFragment extends Fragment { .getDate()), getResources() .getConfiguration() - .locale, - "pretty", - requireContext())), + .locale)), HtmlCompat.FROM_HTML_MODE_COMPACT)); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/NotesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/NotesFragment.java new file mode 100644 index 00000000..ec1fa73c --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/NotesFragment.java @@ -0,0 +1,206 @@ +package org.mian.gitnex.fragments; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.SearchView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import java.util.ArrayList; +import java.util.List; +import org.mian.gitnex.R; +import org.mian.gitnex.activities.CreateNoteActivity; +import org.mian.gitnex.activities.MainActivity; +import org.mian.gitnex.adapters.NotesAdapter; +import org.mian.gitnex.database.api.BaseApi; +import org.mian.gitnex.database.api.NotesApi; +import org.mian.gitnex.database.models.Notes; +import org.mian.gitnex.databinding.FragmentNotesBinding; +import org.mian.gitnex.helpers.Toasty; + +/** + * @author M M Arif + */ +public class NotesFragment extends Fragment { + + private FragmentNotesBinding binding; + private Context ctx; + private NotesAdapter adapter; + private NotesApi notesApi; + private List notesList; + private Intent noteIntent; + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + binding = FragmentNotesBinding.inflate(inflater, container, false); + + ctx = getContext(); + setHasOptionsMenu(true); + + ((MainActivity) requireActivity()) + .setActionBarTitle(getResources().getString(R.string.navNotes)); + + noteIntent = new Intent(ctx, CreateNoteActivity.class); + + binding.newNote.setOnClickListener( + view -> { + noteIntent.putExtra("action", "add"); + ctx.startActivity(noteIntent); + }); + + notesList = new ArrayList<>(); + notesApi = BaseApi.getInstance(ctx, NotesApi.class); + + binding.recyclerView.setHasFixedSize(true); + binding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); + + binding.recyclerView.setPadding(0, 0, 0, 220); + binding.recyclerView.setClipToPadding(false); + + adapter = new NotesAdapter(ctx, notesList); + + binding.pullToRefresh.setOnRefreshListener( + () -> + new Handler(Looper.getMainLooper()) + .postDelayed( + () -> { + notesList.clear(); + binding.pullToRefresh.setRefreshing(false); + binding.progressBar.setVisibility(View.VISIBLE); + fetchDataAsync(); + }, + 250)); + + fetchDataAsync(); + + return binding.getRoot(); + } + + @Override + public void onResume() { + super.onResume(); + fetchDataAsync(); + } + + private void fetchDataAsync() { + + notesApi.fetchAllNotes() + .observe( + getViewLifecycleOwner(), + allNotes -> { + binding.pullToRefresh.setRefreshing(false); + assert allNotes != null; + if (allNotes.size() > 0) { + + notesList.clear(); + binding.noData.setVisibility(View.GONE); + notesList.addAll(allNotes); + adapter.notifyDataChanged(); + binding.recyclerView.setAdapter(adapter); + } else { + + binding.noData.setVisibility(View.VISIBLE); + } + binding.progressBar.setVisibility(View.GONE); + }); + } + + private void filter(String text) { + + List arr = new ArrayList<>(); + + for (Notes d : notesList) { + + if (d == null || d.getContent() == null) { + continue; + } + + if (d.getContent().toLowerCase().contains(text)) { + arr.add(d); + } + } + + adapter.updateList(arr); + } + + public void deleteAllNotes() { + + if (notesList.size() > 0) { + + notesApi.deleteAllNotes(); + notesList.clear(); + adapter.notifyDataChanged(); + Toasty.success( + ctx, ctx.getResources().getQuantityString(R.plurals.noteDeleteMessage, 2)); + } else { + Toasty.warning(ctx, getResources().getString(R.string.noDataFound)); + } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + + inflater.inflate(R.menu.reset_menu, menu); + inflater.inflate(R.menu.search_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + + MenuItem searchItem = menu.findItem(R.id.action_search); + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setOnQueryTextListener( + new SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + + filter(newText); + return false; + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + if (item.getItemId() == R.id.reset_menu_item) { + + if (notesList.size() == 0) { + Toasty.warning(ctx, getResources().getString(R.string.noDataFound)); + } else { + new MaterialAlertDialogBuilder(ctx) + .setTitle(R.string.menuDeleteText) + .setMessage(R.string.notesAllDeletionMessage) + .setPositiveButton( + R.string.menuDeleteText, + (dialog, which) -> { + deleteAllNotes(); + dialog.dismiss(); + }) + .setNeutralButton(R.string.cancelButton, null) + .show(); + } + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java index e8ed1828..975fb496 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java @@ -32,7 +32,6 @@ import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.TimeHelper; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.contexts.RepositoryContext; import retrofit2.Call; @@ -70,7 +69,6 @@ public class RepoInfoFragment extends Fragment { @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentRepoInfoBinding.inflate(inflater, container, false); - TinyDB tinyDb = TinyDB.getInstance(getContext()); ctx = getContext(); Locale locale = getResources().getConfiguration().locale; @@ -79,7 +77,7 @@ public class RepoInfoFragment extends Fragment { binding.repoMetaFrame.setVisibility(View.GONE); - setRepoInfo(locale, tinyDb.getString("dateFormat", "pretty")); + setRepoInfo(locale); if (isExpandViewVisible()) { toggleExpandView(); @@ -147,7 +145,7 @@ public class RepoInfoFragment extends Fragment { return binding.repoMetaFrame.getVisibility() == View.VISIBLE; } - private void setRepoInfo(Locale locale, final String timeFormat) { + private void setRepoInfo(Locale locale) { Repository repoInfo = repository.getRepository(); if (isAdded()) { @@ -208,17 +206,13 @@ public class RepoInfoFragment extends Fragment { FileUtils.byteCountToDisplaySize(repoInfo.getSize() * 1024)); binding.repoMetaCreatedAt.setText( - TimeHelper.formatTime(repoInfo.getCreatedAt(), locale, timeFormat, ctx)); - if (timeFormat.equals("pretty")) { - binding.repoMetaCreatedAt.setOnClickListener( - new ClickListener( - TimeHelper.customDateFormatForToastDateFormat( - repoInfo.getCreatedAt()), - ctx)); - } + TimeHelper.formatTime(repoInfo.getCreatedAt(), locale)); + binding.repoMetaCreatedAt.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreatedAt()), + ctx)); - String repoMetaUpdatedAt = - TimeHelper.formatTime(repoInfo.getUpdatedAt(), locale, timeFormat, ctx); + String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdatedAt(), locale); String website = (repoInfo.getWebsite().isEmpty()) diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java index ac3f3ca1..cf569d35 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java @@ -74,7 +74,7 @@ public class DetailFragment extends Fragment { Call call = RetrofitClient.getApiInterface(context).userGet(username); call.enqueue( - new Callback() { + new Callback<>() { @Override public void onResponse( @@ -94,7 +94,6 @@ public class DetailFragment extends Fragment { : ""; int imgRadius = AppUtil.getPixelsFromDensity(context, 3); - String timeFormat = tinyDb.getString("dateFormat", "pretty"); binding.userFullName.setText(username); binding.userLogin.setText( @@ -151,19 +150,12 @@ public class DetailFragment extends Fragment { binding.userJoinedOn.setText( TimeHelper.formatTime( - response.body().getCreated(), - locale, - timeFormat, + response.body().getCreated(), locale)); + binding.userJoinedOn.setOnClickListener( + new ClickListener( + TimeHelper.customDateFormatForToastDateFormat( + response.body().getCreated()), context)); - if (timeFormat.equals("pretty")) { - binding.userJoinedOn.setOnClickListener( - new ClickListener( - TimeHelper - .customDateFormatForToastDateFormat( - response.body() - .getCreated()), - context)); - } break; case 401: diff --git a/app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java b/app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java index 1fdac369..0cdab2aa 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java +++ b/app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java @@ -1,6 +1,5 @@ package org.mian.gitnex.helpers; -import android.content.Context; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -9,7 +8,6 @@ import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.Locale; -import org.mian.gitnex.R; import org.ocpsoft.prettytime.PrettyTime; /** @@ -35,38 +33,11 @@ public class TimeHelper { return customDateFormatForToastDateFormat(createdTime); } - public static String formatTime(Date date, Locale locale, String timeFormat, Context context) { + public static String formatTime(Date date, Locale locale) { if (date != null) { - switch (timeFormat) { - case "pretty": - { - PrettyTime prettyTime = new PrettyTime(locale); - return prettyTime.format(date); - } - case "normal": - { - DateFormat formatter = - new SimpleDateFormat( - "yyyy-MM-dd '" - + context.getResources() - .getString(R.string.timeAtText) - + "' HH:mm", - locale); - return formatter.format(date); - } - case "normal1": - { - DateFormat formatter = - new SimpleDateFormat( - "dd-MM-yyyy '" - + context.getResources() - .getString(R.string.timeAtText) - + "' HH:mm", - locale); - return formatter.format(date); - } - } + PrettyTime prettyTime = new PrettyTime(locale); + return prettyTime.format(date); } return ""; diff --git a/app/src/main/res/drawable/ic_notes.xml b/app/src/main/res/drawable/ic_notes.xml new file mode 100644 index 00000000..0d627d72 --- /dev/null +++ b/app/src/main/res/drawable/ic_notes.xml @@ -0,0 +1,34 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_create_note.xml b/app/src/main/res/layout/activity_create_note.xml new file mode 100644 index 00000000..c568b4ce --- /dev/null +++ b/app/src/main/res/layout/activity_create_note.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_settings_appearance.xml b/app/src/main/res/layout/activity_settings_appearance.xml index dfe2d646..c398f61f 100644 --- a/app/src/main/res/layout/activity_settings_appearance.xml +++ b/app/src/main/res/layout/activity_settings_appearance.xml @@ -180,39 +180,6 @@ - - - - - - - - + android:layout_marginBottom="@dimen/dimen6dp" + android:padding="@dimen/dimen16dp"> + app:srcCompat="@drawable/ic_people" /> @@ -41,11 +42,11 @@ android:id="@+id/adminUsers" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="12dp" - android:paddingEnd="12dp" + android:paddingStart="@dimen/dimen12dp" + android:paddingEnd="@dimen/dimen12dp" android:text="@string/adminUsers" android:textColor="?attr/primaryTextColor" - android:textSize="16sp"/> + android:textSize="@dimen/dimen16sp" /> @@ -53,16 +54,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/generalImgContentText" - app:srcCompat="@drawable/ic_chevron_right"/> + app:srcCompat="@drawable/ic_chevron_right" /> - - + android:layout_marginBottom="@dimen/dimen6dp" + android:padding="@dimen/dimen16dp"> + app:srcCompat="@drawable/ic_tasks" /> @@ -90,11 +86,11 @@ android:id="@+id/adminCron" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="12dp" - android:paddingEnd="12dp" + android:paddingStart="@dimen/dimen12dp" + android:paddingEnd="@dimen/dimen12dp" android:text="@string/adminCron" android:textColor="?attr/primaryTextColor" - android:textSize="16sp"/> + android:textSize="@dimen/dimen16sp" /> @@ -102,15 +98,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/generalImgContentText" - app:srcCompat="@drawable/ic_chevron_right"/> + app:srcCompat="@drawable/ic_chevron_right" /> - - + android:layout_marginBottom="@dimen/dimen6dp" + android:padding="@dimen/dimen16dp"> + app:srcCompat="@drawable/ic_directory" /> @@ -138,11 +130,11 @@ android:id="@+id/unadoptedRepos" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="12dp" - android:paddingEnd="12dp" + android:paddingStart="@dimen/dimen12dp" + android:paddingEnd="@dimen/dimen12dp" android:text="@string/unadoptedRepos" android:textColor="?attr/primaryTextColor" - android:textSize="16sp"/> + android:textSize="@dimen/dimen16sp" /> @@ -150,7 +142,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/generalImgContentText" - app:srcCompat="@drawable/ic_chevron_right"/> + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_notes.xml b/app/src/main/res/layout/fragment_notes.xml new file mode 100644 index 00000000..ceffa19c --- /dev/null +++ b/app/src/main/res/layout/fragment_notes.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_most_visited_repos.xml b/app/src/main/res/layout/list_most_visited_repos.xml index 705bf547..600747e7 100644 --- a/app/src/main/res/layout/list_most_visited_repos.xml +++ b/app/src/main/res/layout/list_most_visited_repos.xml @@ -97,7 +97,7 @@ android:gravity="center_vertical|end" android:orientation="horizontal" android:paddingStart="@dimen/dimen6dp" - android:paddingEnd="@dimen/dimen6dp"> + android:paddingEnd="@dimen/dimen0dp"> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/drawer_menu.xml b/app/src/main/res/menu/drawer_menu.xml index 3a61c3b1..8340a5b5 100644 --- a/app/src/main/res/menu/drawer_menu.xml +++ b/app/src/main/res/menu/drawer_menu.xml @@ -42,6 +42,10 @@ android:icon="@drawable/ic_trending" android:title="@string/navMostVisited"/> + + diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml index fe858ea7..6ba4e45b 100644 --- a/app/src/main/res/values/settings.xml +++ b/app/src/main/res/values/settings.xml @@ -20,11 +20,6 @@ uk - - @string/settingsDateTimeHeaderDefault - @string/settingsDateTimeNormal - - Roboto Manrope @@ -63,6 +58,7 @@ @string/pageTitleNotifications @string/navMyIssues @string/navMostVisited + @string/navNotes diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 06d41a27..0f6cd6ce 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,6 +32,7 @@ Administration My Issues Most Visited Repos + Notes @@ -199,13 +200,10 @@ Delete Trusted Certificates Delete Trusted Certificates? Are you sure to delete any manually trusted certificate or hostname? \n\nYou will also be logged out. - Date & Time Settings saved Language English Appearance - Pretty - Normal Choose Language Light Theme Switch Time Dark Theme Switch Time @@ -791,6 +789,19 @@ Code Editor Open in Code Editor + + New Note + Edit Note + Start taking your notes here + Created %s + Updated %s + Do you really want to delete this note? + + Note deleted successfully + Notes deleted successfully + + This will delete all of your notes. This action cannot be undone. + commit %1$s added %2$s %3$s