Merge remote-tracking branch 'upstream/main' into commit-status

This commit is contained in:
qwerty287 2022-10-01 08:30:02 +02:00
commit f29d64669b
No known key found for this signature in database
GPG key ID: E0464C650D9D25B2
72 changed files with 2933 additions and 1605 deletions

View file

@ -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)

View file

@ -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'
@ -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"

View file

@ -169,6 +169,10 @@
android:name=".activities.CodeEditorActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".activities.CreateNoteActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize" />
<meta-data
android:name="com.samsung.android.keepalive.density"

View file

@ -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<Character, Character> 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<Code> codeList = languageManager.getLanguageCodeList(currentLanguage);
List<Code> 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() {

View file

@ -0,0 +1,182 @@
package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
import com.vdurmont.emoji.EmojiParser;
import java.time.Instant;
import java.util.Objects;
import org.mian.gitnex.R;
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.ActivityCreateNoteBinding;
import org.mian.gitnex.helpers.Markdown;
/**
* @author M M Arif
*/
public class CreateNoteActivity extends BaseActivity {
private ActivityCreateNoteBinding binding;
private boolean renderMd = false;
private String action;
private Notes notes;
private NotesApi notesApi;
private int noteId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityCreateNoteBinding.inflate(getLayoutInflater());
notesApi = BaseApi.getInstance(ctx, NotesApi.class);
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.showSoftInput(binding.noteContent, InputMethodManager.SHOW_IMPLICIT);
binding.noteContent.requestFocus();
binding.close.setOnClickListener(view -> 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);
}
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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() {

View file

@ -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(

View file

@ -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);

View file

@ -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<Void> call = RetrofitClient.getApiInterface(ctx).adminCronRun(taskName);
call.enqueue(
new Callback<Void>() {
new Callback<>() {
@Override
public void onResponse(

View file

@ -135,7 +135,6 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter<RecyclerView.View
}
public interface OnLoadMoreListener {
void onLoadMore();
void onLoadFinished();

View file

@ -141,9 +141,7 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
.getCommit()
.getCommitter()
.getDate()),
context.getResources().getConfiguration().locale,
"pretty",
context)),
context.getResources().getConfiguration().locale)),
HtmlCompat.FROM_HTML_MODE_COMPACT));
} else {
commitAuthorAndCommitter.setText(
@ -157,9 +155,7 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
.getCommit()
.getCommitter()
.getDate()),
context.getResources().getConfiguration().locale,
"pretty",
context)),
context.getResources().getConfiguration().locale)),
HtmlCompat.FROM_HTML_MODE_COMPACT));
}
@ -179,7 +175,6 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
.resize(120, 120)
.centerCrop()
.into(commitAuthorAvatar);
} else {
commitAuthorAvatar.setImageDrawable(null);
commitAuthorAvatarFrame.setVisibility(View.GONE);
@ -206,7 +201,6 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
.resize(120, 120)
.centerCrop()
.into(commitCommitterAvatar);
} else {
commitCommitterAvatar.setImageDrawable(null);
commitCommitterAvatarFrame.setVisibility(View.GONE);

View file

@ -20,8 +20,6 @@ import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import org.gitnex.tea4j.v2.models.Issue;
@ -38,7 +36,6 @@ import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import org.ocpsoft.prettytime.PrettyTime;
/**
* @author M M Arif
@ -201,7 +198,6 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter<RecyclerView.View
int imgRadius = AppUtil.getPixelsFromDensity(context, 60);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
PicassoService.getInstance(context)
.get()
@ -319,46 +315,11 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter<RecyclerView.View
context.getResources().getColor(R.color.releasePre, null));
}
switch (timeFormat) {
case "pretty":
{
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(issue.getCreatedAt());
issueCreatedTime.setText(createdTime);
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());
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());
issueCreatedTime.setText(createdTime);
break;
}
}
issueCreatedTime.setText(TimeHelper.formatTime(issue.getCreatedAt(), locale));
issueCreatedTime.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(issue.getCreatedAt()),
context));
}
}
}

View file

@ -14,8 +14,6 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import org.mian.gitnex.R;
@ -27,7 +25,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.RepositoryContext;
import org.ocpsoft.prettytime.PrettyTime;
/**
* @author M M Arif
@ -129,13 +126,11 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<RecyclerVie
});
}
@SuppressLint("SetTextI18n")
void bindData(org.gitnex.tea4j.v2.models.Repository userRepositories) {
this.userRepositories = userRepositories;
int imgRadius = AppUtil.getPixelsFromDensity(context, 60);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
orgName.setText(userRepositories.getFullName().split("/")[0]);
repoName.setText(userRepositories.getFullName().split("/")[1]);
@ -174,50 +169,15 @@ public class ExploreRepositoriesAdapter extends RecyclerView.Adapter<RecyclerVie
}
if (userRepositories.getUpdatedAt() != null) {
switch (timeFormat) {
case "pretty":
{
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(userRepositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
userRepositories.getUpdatedAt()),
context));
break;
}
case "normal":
{
DateFormat formatter =
new SimpleDateFormat(
"yyyy-MM-dd '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(userRepositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1":
{
DateFormat formatter =
new SimpleDateFormat(
"dd-MM-yyyy '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(userRepositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
repoLastUpdated.setText(
context.getString(
R.string.lastUpdatedAt,
TimeHelper.formatTime(userRepositories.getUpdatedAt(), locale)));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
userRepositories.getUpdatedAt()),
context));
} else {
repoLastUpdated.setVisibility(View.GONE);
}

View file

@ -50,6 +50,7 @@ import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.Markdown;
@ -455,7 +456,6 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<RecyclerView.View
void bindData(TimelineComment timelineComment) {
int fontSize = 14;
String timeFormat = tinyDB.getString("dateFormat", "pretty");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
userLoginId = timelineComment.getUser().getLogin();
@ -469,34 +469,20 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<RecyclerView.View
StringBuilder infoBuilder = null;
if (issueComment.getCreatedAt() != null) {
if (timeFormat.equals("pretty")) {
infoBuilder =
new StringBuilder(
TimeHelper.formatTime(
issueComment.getCreatedAt(),
locale,
"pretty",
context));
information.setOnClickListener(
v ->
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();

View file

@ -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<RecyclerView.ViewHolder>
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<RecyclerView.ViewHolder>
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));
}
}
}

View file

@ -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<RecyclerView.ViewHol
void bindData(Milestone dataModel) {
this.milestones = dataModel;
final TinyDB tinyDb = TinyDB.getInstance(context);
final String locale = context.getResources().getConfiguration().locale.getLanguage();
final String timeFormat = tinyDb.getString("dateFormat", "pretty");
Markdown.render(context, dataModel.getTitle(), msTitle);
@ -249,39 +246,23 @@ public class MilestonesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
if (dataModel.getDueOn() != null) {
String TAG = "MilestonesAdapter";
if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = dataModel.getDueOn();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
Date date = dataModel.getDueOn();
assert date != null;
String dueDate = formatter.format(date);
assert date != null;
String dueDate = formatter.format(date);
if (date.before(new Date())) {
msDueDate.setTextColor(
ResourcesCompat.getColor(
context.getResources(), R.color.darkRed, null));
}
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
dataModel.getDueOn()),
context));
} else if (timeFormat.equals("normal1")) {
SimpleDateFormat formatter =
new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
Date date1 = dataModel.getDueOn();
assert date1 != null;
String dueDate = formatter.format(date1);
msDueDate.setText(dueDate);
if (date.before(new Date())) {
msDueDate.setTextColor(
ResourcesCompat.getColor(
context.getResources(), R.color.darkRed, null));
}
msDueDate.setText(dueDate);
msDueDate.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(dataModel.getDueOn()),
context));
} else {
msDueDate.setText(context.getString(R.string.milestoneNoDueDate));

View file

@ -0,0 +1,152 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.CreateNoteActivity;
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.helpers.Markdown;
import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty;
/**
* @author M M Arif
*/
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesViewHolder> {
private List<Notes> notesList;
private final Context ctx;
private final Intent noteIntent;
public NotesAdapter(Context ctx, List<Notes> 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<Notes> list) {
notesList = list;
notifyDataChanged();
}
}

View file

@ -175,12 +175,10 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
500);
}
@SuppressLint("SetTextI18n")
void bindData(PullRequest pullRequest) {
TinyDB tinyDb = TinyDB.getInstance(context);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context)
@ -289,8 +287,7 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
prNumber_ + " " + EmojiParser.parseToUnicode(pullRequest.getTitle()),
HtmlCompat.FROM_HTML_MODE_LEGACY));
this.prCommentsCount.setText(String.valueOf(pullRequest.getComments()));
this.prCreatedTime.setText(
TimeHelper.formatTime(pullRequest.getCreatedAt(), locale, timeFormat, context));
this.prCreatedTime.setText(TimeHelper.formatTime(pullRequest.getCreatedAt(), locale));
if (pullRequest.getComments() > 15) {
commentIcon.setImageDrawable(
@ -299,13 +296,11 @@ public class PullRequestsAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
context.getResources().getColor(R.color.releasePre, null));
}
if (timeFormat.equals("pretty")) {
this.prCreatedTime.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
pullRequest.getCreatedAt()),
context));
}
this.prCreatedTime.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
pullRequest.getCreatedAt()),
context));
}
}
}

View file

@ -30,7 +30,6 @@ import org.mian.gitnex.helpers.ClickListener;
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.structs.FragmentRefreshListener;
import retrofit2.Call;
@ -78,9 +77,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
@Override
public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
final TinyDB tinyDb = TinyDB.getInstance(context);
final Locale locale = context.getResources().getConfiguration().locale;
final String timeFormat = tinyDb.getString("dateFormat", "pretty");
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Release currentItem = releasesList.get(position);
@ -120,18 +117,13 @@ public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.Releas
}
if (currentItem.getPublishedAt() != null) {
holder.releaseDate.setText(
TimeHelper.formatTime(
currentItem.getPublishedAt(), locale, timeFormat, context));
holder.releaseDate.setText(TimeHelper.formatTime(currentItem.getPublishedAt(), locale));
}
if (timeFormat.equals("pretty")) {
holder.releaseDate.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
currentItem.getPublishedAt()),
context));
}
holder.releaseDate.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(currentItem.getPublishedAt()),
context));
if (!currentItem.getBody().equals("")) {
Markdown.render(context, currentItem.getBody(), holder.releaseBodyContent);

View file

@ -14,8 +14,6 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import org.mian.gitnex.R;
@ -27,7 +25,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.RepositoryContext;
import org.ocpsoft.prettytime.PrettyTime;
/**
* @author M M Arif
@ -126,7 +123,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
this.userRepositories = forksModel;
orgName.setText(forksModel.getFullName().split("/")[0]);
repoName.setText(forksModel.getFullName().split("/")[1]);
@ -165,50 +161,15 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
}
if (forksModel.getUpdatedAt() != null) {
switch (timeFormat) {
case "pretty":
{
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(forksModel.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
forksModel.getUpdatedAt()),
context));
break;
}
case "normal":
{
DateFormat formatter =
new SimpleDateFormat(
"yyyy-MM-dd '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(forksModel.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1":
{
DateFormat formatter =
new SimpleDateFormat(
"dd-MM-yyyy '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(forksModel.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
repoLastUpdated.setText(
context.getString(
R.string.lastUpdatedAt,
TimeHelper.formatTime(forksModel.getUpdatedAt(), locale)));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
forksModel.getUpdatedAt()),
context));
} else {
repoLastUpdated.setVisibility(View.GONE);
}

View file

@ -16,8 +16,6 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@ -30,7 +28,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.RepositoryContext;
import org.ocpsoft.prettytime.PrettyTime;
/**
* @author M M Arif
@ -200,7 +197,6 @@ public class ReposListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
int imgRadius = AppUtil.getPixelsFromDensity(context, 60);
Locale locale = context.getResources().getConfiguration().locale;
String timeFormat = tinyDb.getString("dateFormat", "pretty");
orgName.setText(repositories.getFullName().split("/")[0]);
repoName.setText(repositories.getFullName().split("/")[1]);
repoStars.setText(AppUtil.numberFormatter(repositories.getStarsCount()));
@ -238,50 +234,12 @@ public class ReposListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
}
if (repositories.getUpdatedAt() != null) {
switch (timeFormat) {
case "pretty":
{
PrettyTime prettyTime = new PrettyTime(locale);
String createdTime = prettyTime.format(repositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
repositories.getUpdatedAt()),
context));
break;
}
case "normal":
{
DateFormat formatter =
new SimpleDateFormat(
"yyyy-MM-dd '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(repositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
case "normal1":
{
DateFormat formatter =
new SimpleDateFormat(
"dd-MM-yyyy '"
+ context.getResources()
.getString(R.string.timeAtText)
+ "' HH:mm",
locale);
String createdTime = formatter.format(repositories.getUpdatedAt());
repoLastUpdated.setText(
context.getString(R.string.lastUpdatedAt, createdTime));
break;
}
}
repoLastUpdated.setText(TimeHelper.formatTime(repositories.getUpdatedAt(), locale));
repoLastUpdated.setOnClickListener(
new ClickListener(
TimeHelper.customDateFormatForToastDateFormat(
repositories.getUpdatedAt()),
context));
} else {
repoLastUpdated.setVisibility(View.GONE);
}

View file

@ -281,9 +281,7 @@ public class WikiListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
.getLastCommit()
.getAuthor()
.getDate()),
ctx.getResources().getConfiguration().locale,
"pretty",
ctx)),
ctx.getResources().getConfiguration().locale)),
HtmlCompat.FROM_HTML_MODE_COMPACT));
this.wikiLastUpdatedBy.setOnClickListener(
new ClickListener(
@ -297,23 +295,19 @@ public class WikiListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
ColorGenerator generator = ColorGenerator.Companion.getMATERIAL();
int color = generator.getColor(wikiPageMetaData.getTitle());
if (wikiPageMetaData.getTitle() != null && wikiPageMetaData.getTitle().length() > 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);

View file

@ -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);
}

View file

@ -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<String> languages() {
return defaultGrammarLocator.languages();
}
}

View file

@ -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<List<Notes>> 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));
}
}
}

View file

@ -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<List<Notes>> 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);
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -242,9 +242,7 @@ public class CommitDetailFragment extends Fragment {
.getDate()),
getResources()
.getConfiguration()
.locale,
"pretty",
requireContext())),
.locale)),
HtmlCompat.FROM_HTML_MODE_COMPACT));
} else {
binding.commitAuthorAndCommitter.setText(
@ -263,9 +261,7 @@ public class CommitDetailFragment extends Fragment {
.getDate()),
getResources()
.getConfiguration()
.locale,
"pretty",
requireContext())),
.locale)),
HtmlCompat.FROM_HTML_MODE_COMPACT));
}

View file

@ -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<Notes> 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<Notes> 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);
}
}

View file

@ -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())

View file

@ -74,7 +74,7 @@ public class DetailFragment extends Fragment {
Call<User> call = RetrofitClient.getApiInterface(context).userGet(username);
call.enqueue(
new Callback<User>() {
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:

View file

@ -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() {

View file

@ -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 "";

View file

@ -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<Code> 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<Character> 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<Character> 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;
}
}
}

View file

@ -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
}

View file

@ -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);
}
}

View file

@ -1,9 +0,0 @@
package org.mian.gitnex.helpers.codeeditor;
/**
* @author AmrDeveloper
* @author M M Arif
*/
public enum ThemeName {
FIVE_COLOR
}

View file

@ -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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList(Context context) {
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public String getName() {
return "Go";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> 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;
}
}
}

View file

@ -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(<html|<DOCTYPE|<head|<title|<body|<style|<script|src|href"
+ "<h1|<h2|<h3|<h4|<h5|<h6|<br|<hr|<section|<header|<footer|<select|<img|<embed|<iframe|<div|<p|code|strong|small|template|"
+ "input|form|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|)\\b");
public class HtmlLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -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<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> 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[] {
"<html",
"<DOCTYPE",
"<head",
"<title",
"<body",
"<h1",
"<h2",
"<h3",
"<h4",
"<h5",
"<h6",
"<br",
"<hr",
"<section",
"<header",
"<footer",
"<select",
"<img",
"<embed",
"<iframe",
"<style",
"<script",
"<div",
"<p",
"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"
};
}
@Override
public List<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> 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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
characterSet.add('[');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
characterSet.add(']');
return characterSet;
}
}

View file

@ -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<String, Language> 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<Character> getIndentationStarts();
public abstract Set<Character> getIndentationEnds();
public abstract String[] getKeywords();
public abstract List<Code> 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();
}
}

View file

@ -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
}

View file

@ -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(<?php|__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|"
+ "str_replace|form|date|abs|min|max|strtotime|mktime|"
+ "foreach|require_once|include_once|hash|array|range|break|continue|preg_match|preg_match_all|preg_replace|"
+ "throw|new|and|or|if|else|elseif|switch|case|default|match|require|include|goto|do|while|for|map|)\\b");
public class PhpLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -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<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
Set<Character> 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[] {
"<?php",
"__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",
"use",
"enum",
"class"
};
}
@Override
public List<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
}

View file

@ -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<Code> getCodeList(Context context) {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
public static Set<Character> 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<Code> getCodeList() {
List<Code> 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<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add(':');
return characterSet;
}
@Override
public Set<Character> getIndentationEnds() {
return new HashSet<>();
}
}

View file

@ -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";
}
}

View file

@ -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<Character> getIndentationStarts() {
return Set.of();
}
@Override
public Set<Character> getIndentationEnds() {
return Set.of();
}
@Override
public String[] getKeywords() {
return new String[0];
}
@Override
public List<Code> getCodeList() {
return new ArrayList<>();
}
@Override
public String getName() {
return "Unknown";
}
}

View file

@ -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(<xml|version|encoding)\\b");
public class XmlLanguage extends Language {
// Brackets and Colons
private static final Pattern PATTERN_BUILTINS = Pattern.compile("[,:;[->]{}()]");
@ -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 String[] getKeywords(Context context) {
return context.getResources().getStringArray(R.array.xml_keywords);
public static String getCommentEnd() {
return "-->";
}
public static List<Code> 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[] {
"<xml", "encoding", "version",
};
}
@Override
public List<Code> getCodeList() {
List<Code> codeList = new ArrayList<>();
String[] keywords = getKeywords(context);
String[] keywords = getKeywords();
for (String keyword : keywords) {
codeList.add(new Keyword(keyword));
}
return codeList;
}
public static Set<Character> getIndentationStarts() {
@Override
public String getName() {
return "XML";
}
@Override
public Set<Character> getIndentationStarts() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('{');
return characterSet;
}
public static Set<Character> getIndentationEnds() {
@Override
public Set<Character> getIndentationEnds() {
Set<Character> characterSet = new HashSet<>();
characterSet.add('}');
return characterSet;
}
public static String getCommentStart() {
return "//";
}
public static String getCommentEnd() {
return "";
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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()

View file

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M7,3L17,3A2,2 0,0 1,19 5L19,19A2,2 0,0 1,17 21L7,21A2,2 0,0 1,5 19L5,5A2,2 0,0 1,7 3z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M9,7L15,7"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M9,11L15,11"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M9,15L13,15"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView"
app:elevation="@dimen/dimen0dp">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor">
<ImageView
android:id="@+id/close"
android:layout_width="@dimen/dimen26dp"
android:layout_height="@dimen/dimen26dp"
android:layout_marginStart="@dimen/dimen16dp"
android:layout_marginEnd="@dimen/dimen16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/newNote"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<EditText
android:id="@+id/note_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|start"
android:inputType="textCapSentences|textMultiLine"
android:scrollbars="vertical"
android:background="?attr/primaryBackgroundColor"
android:textColor="?attr/inputTextColor"
android:hint="@string/newNoteContentHint"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"
android:autofillHints="@string/newNoteContentHint" />
<TextView
android:id="@+id/markdown_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:textIsSelectable="true"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View file

@ -180,39 +180,6 @@
</LinearLayout>
<LinearLayout
android:id="@+id/timeFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/tvDateTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsDateTimeHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/tvDateTimeSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsDateTimeHeaderDefault"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/counterBadgeFrame"
android:layout_width="match_parent"

View file

@ -21,19 +21,20 @@
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp">
android:layout_marginBottom="@dimen/dimen6dp"
android:padding="@dimen/dimen16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_people"/>
app:srcCompat="@drawable/ic_people" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="@dimen/dimen10dp"
android:layout_marginEnd="@dimen/dimen10dp"
android:layout_weight="1"
android:orientation="vertical">
@ -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" />
</LinearLayout>
@ -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" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor"/>
<LinearLayout
android:id="@+id/adminCronFrame"
android:layout_width="match_parent"
@ -70,19 +65,20 @@
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp">
android:layout_marginBottom="@dimen/dimen6dp"
android:padding="@dimen/dimen16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_tasks"/>
app:srcCompat="@drawable/ic_tasks" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="@dimen/dimen10dp"
android:layout_marginEnd="@dimen/dimen10dp"
android:layout_weight="1"
android:orientation="vertical">
@ -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" />
</LinearLayout>
@ -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" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor"/>
<LinearLayout
android:id="@+id/unadoptedReposFrame"
android:layout_width="match_parent"
@ -118,19 +109,20 @@
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp">
android:layout_marginBottom="@dimen/dimen6dp"
android:padding="@dimen/dimen16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_directory"/>
app:srcCompat="@drawable/ic_directory" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="@dimen/dimen10dp"
android:layout_marginEnd="@dimen/dimen10dp"
android:layout_weight="1"
android:orientation="vertical">
@ -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" />
</LinearLayout>
@ -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" />
</LinearLayout>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"
android:padding="@dimen/dimen8dp">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
style="@style/Widget.Material3.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
<TextView
android:id="@+id/noData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/dimen16dp"
android:gravity="center"
android:text="@string/noDataFound"
android:textColor="?attr/primaryTextColor"
android:textSize="18sp"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/newNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/dimen16dp"
android:text="@string/newNote"
android:contentDescription="@string/newNote"
android:textColor="@color/colorWhite"
android:backgroundTint="?attr/fabColor"
app:iconTint="@color/colorWhite"
app:icon="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -97,7 +97,7 @@
android:gravity="center_vertical|end"
android:orientation="horizontal"
android:paddingStart="@dimen/dimen6dp"
android:paddingEnd="@dimen/dimen6dp">
android:paddingEnd="@dimen/dimen0dp">
<ImageView
android:id="@+id/reset_counter"

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/dimen4dp"
android:paddingBottom="@dimen/dimen4dp">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/materialCardViewFilledStyle"
app:cardElevation="@dimen/dimen0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
android:background="?attr/materialCardBackgroundColor"
android:padding="@dimen/dimen12dp"
android:orientation="vertical">
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/repoName"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
<View
android:id="@+id/spacer_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen8dp" />
<LinearLayout
android:id="@+id/note_info_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/datetime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen12sp"
tools:text="@string/noteDateTime" />
<LinearLayout
android:id="@+id/note_info_end_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen10dp"
android:gravity="center_vertical|end"
android:orientation="horizontal"
android:paddingStart="@dimen/dimen6dp"
android:paddingEnd="@dimen/dimen0dp">
<ImageView
android:id="@+id/delete_note"
android:layout_width="@dimen/dimen18dp"
android:layout_height="@dimen/dimen18dp"
android:layout_marginStart="@dimen/dimen16dp"
android:layout_marginEnd="@dimen/dimen2dp"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_delete"
app:tint="?attr/iconsColor" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View file

@ -42,6 +42,10 @@
android:icon="@drawable/ic_trending"
android:title="@string/navMostVisited"/>
<item android:id="@+id/nav_notes"
android:icon="@drawable/ic_notes"
android:title="@string/navNotes" />
<item android:id="@+id/nav_comments_draft"
android:icon="@drawable/ic_drafts"
android:title="@string/titleDrafts"/>

View file

@ -74,4 +74,6 @@
<color name="five_dark_grey">#a9b1ae</color>
<color name="five_dark_white">#ffffff</color>
<color name="gold">#e6b121</color>
<color name="five_yellow">#fdc92f</color>
<color name="five_background_grey">#f5f2f0</color>
</resources>

View file

@ -1,304 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--HTML Keywords List-->
<string-array name="html_keywords">
<item><![CDATA[<html]]></item>
<item><![CDATA[<DOCTYPE]]></item>
<item><![CDATA[<head]]></item>
<item><![CDATA[<title]]></item>
<item><![CDATA[<body]]></item>
<item><![CDATA[<h1]]></item>
<item><![CDATA[<h2]]></item>
<item><![CDATA[<h3]]></item>
<item><![CDATA[<h4]]></item>
<item><![CDATA[<h5]]></item>
<item><![CDATA[<h6]]></item>
<item><![CDATA[<br]]></item>
<item><![CDATA[<hr]]></item>
<item><![CDATA[<section]]></item>
<item><![CDATA[<header]]></item>
<item><![CDATA[<footer]]></item>
<item><![CDATA[<select]]></item>
<item><![CDATA[<img]]></item>
<item><![CDATA[<embed]]></item>
<item><![CDATA[<iframe]]></item>
<item><![CDATA[<style]]></item>
<item><![CDATA[<script]]></item>
<item><![CDATA[<div]]></item>
<item><![CDATA[<p]]></item>
<item>code</item>
<item>strong</item>
<item>small</item>
<item>template</item>
<item>form</item>
<item>input</item>
<item>textarea</item>
<item>button</item>
<item>option</item>
<item>label</item>
<item>fieldset</item>
<item>legend</item>
<item>datalist</item>
<item>frame</item>
<item>map</item>
<item>area</item>
<item>canvas</item>
<item>picture</item>
<item>svg</item>
<item>audio</item>
<item>source</item>
<item>track</item>
<item>video</item>
<item>link</item>
<item>nav</item>
<item>ul</item>
<item>ol</item>
<item>li</item>
<item>table</item>
<item>caption</item>
<item>th</item>
<item>tr</item>
<item>td</item>
<item>thead</item>
<item>tbody</item>
<item>tfooter</item>
<item>col</item>
<item>span</item>
<item>main</item>
<item>article</item>
<item>aside</item>
<item>meta</item>
<item>base</item>
<item>noscript</item>
<item>object</item>
<item>param</item>
<item>src</item>
<item>href</item>
</string-array>
<!--XML Keywords List-->
<string-array name="xml_keywords">
<item><![CDATA[<xml]]></item>
<item>encoding</item>
<item>version</item>
</string-array>
<!--PHP Keywords List-->
<string-array name="php_keywords">
<item><![CDATA[<?php]]></item>
<item>__construct</item>
<item>var_dump</item>
<item>define</item>
<item>echo</item>
<item>var</item>
<item>float</item>
<item>int</item>
<item>bool</item>
<item>false</item>
<item>true</item>
<item>function</item>
<item>private</item>
<item>public</item>
<item>protected</item>
<item>interface</item>
<item>return</item>
<item>copy</item>
<item>struct</item>
<item>abstract</item>
<item>extends</item>
<item>trait</item>
<item>static</item>
<item>namespace</item>
<item>implements</item>
<item>__set</item>
<item>__get</item>
<item>unlink</item>
<item>this</item>
<item>try</item>
<item>catch</item>
<item>Throwable</item>
<item>Exception</item>
<item>pdo</item>
<item>throw</item>
<item>new</item>
<item>and</item>
<item>or</item>
<item>if</item>
<item>else</item>
<item>elseif</item>
<item>switch</item>
<item>case</item>
<item>default</item>
<item>match</item>
<item>require</item>
<item>include</item>
<item>require_once</item>
<item>include_once</item>
<item>goto</item>
<item>do</item>
<item>while</item>
<item>for</item>
<item>foreach</item>
<item>map</item>
<item>hash</item>
<item>array</item>
<item>range</item>
<item>break</item>
<item>continue</item>
<item>preg_match</item>
<item>preg_match_all</item>
<item>preg_replace</item>
<item>str_replace</item>
<item>form</item>
<item>date</item>
<item>abs</item>
<item>min</item>
<item>max</item>
<item>strtotime</item>
<item>mktime</item>
</string-array>
<!--Java Keywords List-->
<string-array name="java_keywords">
<item>public</item>
<item>private</item>
<item>protected</item>
<item>package</item>
<item>abstract</item>
<item>boolean</item>
<item>break</item>
<item>byte</item>
<item>case</item>
<item>catch</item>
<item>char</item>
<item>class</item>
<item>continue</item>
<item>default</item>
<item>do</item>
<item>double</item>
<item>else</item>
<item>enum</item>
<item>extends</item>
<item>final</item>
<item>finally</item>
<item>float</item>
<item>for</item>
<item>if</item>
<item>implements</item>
<item>import</item>
<item>instanceof</item>
<item>int</item>
<item>interface</item>
<item>long</item>
<item>native</item>
<item>new</item>
<item>return</item>
<item>short</item>
<item>static</item>
<item>strictfp</item>
<item>super</item>
<item>switch</item>
<item>synchronized</item>
<item>this</item>
<item>throw</item>
<item>transient</item>
<item>try</item>
<item>void</item>
<item>volatile</item>
<item>while</item>
</string-array>
<!--GoLang Keywords List-->
<string-array name="go_keywords">
<item>break</item>
<item>default</item>
<item>func</item>
<item>interface</item>
<item>select</item>
<item>case</item>
<item>defer</item>
<item>go</item>
<item>map</item>
<item>struct</item>
<item>chan</item>
<item>else</item>
<item>goto</item>
<item>package</item>
<item>switch</item>
<item>const</item>
<item>fallthrough</item>
<item>if</item>
<item>bool</item>
<item>byte</item>
<item>cap</item>
<item>close</item>
<item>complex</item>
<item>complex64</item>
<item>complex128</item>
<item>uint16</item>
<item>copy</item>
<item>false</item>
<item>float32</item>
<item>float64</item>
<item>imag</item>
<item>int</item>
<item>int8</item>
<item>int16</item>
<item>uint32</item>
<item>int32</item>
<item>int64</item>
<item>len</item>
<item>make</item>
<item>new</item>
<item>nil</item>
<item>uint64</item>
<item>range</item>
<item>type</item>
<item>continue</item>
<item>for</item>
<item>import</item>
<item>return</item>
<item>var</item>
</string-array>
<!--Python Keywords List-->
<string-array name="python_keywords">
<item>False</item>
<item>await</item>
<item>else</item>
<item>import</item>
<item>pass</item>
<item>None</item>
<item>break</item>
<item>except</item>
<item>in</item>
<item>raise</item>
<item>True</item>
<item>class</item>
<item>finally</item>
<item>is</item>
<item>return</item>
<item>and</item>
<item>continue</item>
<item>for</item>
<item>lambda</item>
<item>try</item>
<item>as</item>
<item>def</item>
<item>from</item>
<item>nonlocal</item>
<item>while</item>
<item>assert</item>
<item>del</item>
<item>global</item>
<item>not</item>
<item>with</item>
<item>async</item>
<item>elif</item>
<item>if</item>
<item>or</item>
<item>yield</item>
</string-array>
</resources>

View file

@ -20,11 +20,6 @@
<item>uk</item>
</string-array>
<string-array name="timeFormats">
<item>@string/settingsDateTimeHeaderDefault</item>
<item>@string/settingsDateTimeNormal</item>
</string-array>
<string-array name="fonts">
<item>Roboto</item>
<item>Manrope</item>
@ -63,6 +58,7 @@
<item>@string/pageTitleNotifications</item>
<item>@string/navMyIssues</item>
<item>@string/navMostVisited</item>
<item>@string/navNotes</item>
</string-array>
<string-array name="linkHandlerDefaultScreen">

View file

@ -32,6 +32,7 @@
<string name="navAdministration">Administration</string>
<string name="navMyIssues">My Issues</string>
<string name="navMostVisited">Most Visited Repos</string>
<string name="navNotes">Notes</string>
<!-- menu items -->
<!-- page titles -->
@ -199,13 +200,10 @@
<string name="settingsCertsSelectorHeader">Delete Trusted Certificates</string>
<string name="settingsCertsPopupTitle">Delete Trusted Certificates?</string>
<string name="settingsCertsPopupMessage">Are you sure to delete any manually trusted certificate or hostname? \n\nYou will also be logged out.</string>
<string name="settingsDateTimeHeaderText">Date &amp; Time</string>
<string name="settingsSave">Settings saved</string>
<string name="settingsLanguageSelectorHeader">Language</string>
<string name="settingsLanguageSelectedHeaderDefault">English</string>
<string name="settingsAppearanceHeader">Appearance</string>
<string name="settingsDateTimeHeaderDefault">Pretty</string>
<string name="settingsDateTimeNormal">Normal</string>
<string name="settingsLanguageSelectorDialogTitle">Choose Language</string>
<string name="settingsLightThemeTimeSelectorHeader">Light Theme Switch Time</string>
<string name="settingsDarkThemeTimeSelectorHeader">Dark Theme Switch Time</string>
@ -791,6 +789,19 @@
<string name="codeEditor" translatable="false">Code Editor</string>
<string name="openInCodeEditor">Open in Code Editor</string>
<!-- notes -->
<string name="newNote">New Note</string>
<string name="editNote">Edit Note</string>
<string name="newNoteContentHint">Start taking your notes here</string>
<string name="noteDateTime">Created %s</string>
<string name="noteTimeModified">Updated %s</string>
<string name="noteDeleteDialoMessage">Do you really want to delete this note?</string>
<plurals name="noteDeleteMessage">
<item quantity="one">Note deleted successfully</item>
<item quantity="other">Notes deleted successfully</item>
</plurals>
<string name="notesAllDeletionMessage">This will delete all of your notes. This action cannot be undone.</string>
<!-- timeline -->
<string name="commitText">commit</string>
<string name="timelineAddedCommit">%1$s added %2$s %3$s</string>