[App Only] Notes (#1207)

Closes #656

It is a simple notes feature where you can add your notes related to your repos, issues etc etc.

For me I sometime came across an issue or thing to fix/add but away from PC. I have notes app, but there are so many things in it and sometime it is lost where I save it. So this will be an easy way to remind me of it when needed.

It can be used as a generic Notes app too.

Co-authored-by: M M Arif <mmarif@swatian.com>
Co-authored-by: qwerty287 <ndev@web.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1207
Reviewed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
M M Arif 2022-10-01 06:16:19 +02:00
parent 211fdab250
commit 07e048e29f
42 changed files with 1193 additions and 592 deletions

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'

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

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

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

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

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

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

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

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