mirror of
https://github.com/gitnex-org/gitnex.git
synced 2026-07-16 01:50:11 -05:00
Create and edit wiki page
This commit is contained in:
@@ -56,8 +56,8 @@ dependencies {
|
||||
def acra = '5.8.4'
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
|
||||
@@ -347,7 +347,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
|
||||
break;
|
||||
case "createWiki":
|
||||
|
||||
startActivity(repository.getIntent(ctx, CodeEditorActivity.class));
|
||||
Intent intent = new Intent(ctx, WikiActivity.class);
|
||||
intent.putExtra("action", "add");
|
||||
intent.putExtra(RepositoryContext.INTENT_EXTRA, ((RepoDetailActivity) ctx).repository);
|
||||
ctx.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,18 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.v2.models.CreateWikiPageOptions;
|
||||
import org.gitnex.tea4j.v2.models.WikiPage;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityWikiBinding;
|
||||
import org.mian.gitnex.fragments.WikiFragment;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Markdown;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.contexts.RepositoryContext;
|
||||
import java.util.Objects;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
|
||||
@@ -28,6 +31,7 @@ public class WikiActivity extends BaseActivity {
|
||||
|
||||
private ActivityWikiBinding binding;
|
||||
private String pageName;
|
||||
private String action;
|
||||
private RepositoryContext repository;
|
||||
private boolean renderMd = true;
|
||||
|
||||
@@ -42,13 +46,152 @@ public class WikiActivity extends BaseActivity {
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
|
||||
if(getIntent().getStringExtra("action") != null) {
|
||||
action = getIntent().getStringExtra("action");
|
||||
}
|
||||
else {
|
||||
action = "";
|
||||
}
|
||||
pageName = getIntent().getStringExtra("pageName");
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
|
||||
binding.toolbarTitle.setMovementMethod(new ScrollingMovementMethod());
|
||||
binding.toolbarTitle.setText(pageName);
|
||||
|
||||
getWikiPageContents();
|
||||
if(action.equalsIgnoreCase("edit")) {
|
||||
getWikiPageContents();
|
||||
binding.renderWiki.setVisibility(View.GONE);
|
||||
binding.wikiTitle.setText(pageName);
|
||||
}
|
||||
else if(action.equalsIgnoreCase("add")) {
|
||||
binding.renderWiki.setVisibility(View.GONE);
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
binding.toolbarTitle.setText(R.string.createWikiPage);
|
||||
binding.createWiki.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
getWikiPageContents();
|
||||
binding.renderWiki.setVisibility(View.VISIBLE);
|
||||
binding.createWiki.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void processWiki() {
|
||||
|
||||
String wikiTitle = binding.wikiTitle.getText() != null ? binding.wikiTitle.getText().toString() : "";
|
||||
String wikiContent = binding.wikiContent.getText() != null ? binding.wikiContent.getText().toString() : "";
|
||||
|
||||
if(wikiTitle.isEmpty() || wikiContent.isEmpty()) {
|
||||
Toasty.error(ctx, getString(R.string.wikiPageNameAndContentError));
|
||||
return;
|
||||
}
|
||||
|
||||
if(action.equalsIgnoreCase("edit")) {
|
||||
patchWiki(wikiTitle, wikiContent);
|
||||
}
|
||||
else if(action.equalsIgnoreCase("add")) {
|
||||
addWiki(wikiTitle, wikiContent);
|
||||
}
|
||||
}
|
||||
|
||||
private void addWiki(String wikiTitle, String wikiContent) {
|
||||
|
||||
CreateWikiPageOptions createWikiPageOptions = new CreateWikiPageOptions();
|
||||
createWikiPageOptions.setTitle(wikiTitle);
|
||||
createWikiPageOptions.setContentBase64(AppUtil.encodeBase64(wikiContent));
|
||||
|
||||
Call<WikiPage> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.repoCreateWikiPage(repository.getOwner(), repository.getName(), createWikiPageOptions);
|
||||
|
||||
call.enqueue(new Callback<>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WikiPage> call, @NonNull retrofit2.Response<WikiPage> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 201) {
|
||||
|
||||
Toasty.success(ctx, getString(R.string.wikiCreated));
|
||||
WikiFragment.resumeWiki = true;
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 401:
|
||||
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx));
|
||||
break;
|
||||
case 403:
|
||||
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
|
||||
break;
|
||||
case 404:
|
||||
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
|
||||
break;
|
||||
default:
|
||||
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.genericError)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WikiPage> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void patchWiki(String wikiTitle, String wikiContent) {
|
||||
|
||||
CreateWikiPageOptions createWikiPageOptions = new CreateWikiPageOptions();
|
||||
createWikiPageOptions.setTitle(wikiTitle);
|
||||
createWikiPageOptions.setContentBase64(AppUtil.encodeBase64(wikiContent));
|
||||
|
||||
Call<WikiPage> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.repoEditWikiPage(repository.getOwner(), repository.getName(), pageName, createWikiPageOptions);
|
||||
|
||||
call.enqueue(new Callback<>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WikiPage> call, @NonNull retrofit2.Response<WikiPage> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
if(response.code() == 200) {
|
||||
|
||||
Toasty.success(ctx, getString(R.string.wikiUpdated));
|
||||
WikiFragment.resumeWiki = true;
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 401:
|
||||
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx));
|
||||
break;
|
||||
case 403:
|
||||
runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
|
||||
break;
|
||||
case 404:
|
||||
runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
|
||||
break;
|
||||
default:
|
||||
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.genericError)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WikiPage> call, @NonNull Throwable t) {
|
||||
|
||||
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getWikiPageContents() {
|
||||
@@ -83,6 +226,10 @@ public class WikiActivity extends BaseActivity {
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if(action.equalsIgnoreCase("edit")) {
|
||||
binding.wikiContent.setText(pageContents);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
@@ -120,6 +267,9 @@ public class WikiActivity extends BaseActivity {
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.files_view_menu, menu);
|
||||
if(action.equalsIgnoreCase("edit") || action.equalsIgnoreCase("add")) {
|
||||
inflater.inflate(R.menu.save, menu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -134,28 +284,47 @@ public class WikiActivity extends BaseActivity {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.edit) {
|
||||
else if(id == R.id.save) {
|
||||
|
||||
processWiki();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.markdown) {
|
||||
|
||||
if(!renderMd) {
|
||||
if(action.equalsIgnoreCase("edit") || action.equalsIgnoreCase("add")) {
|
||||
if(renderMd) {
|
||||
Markdown.render(ctx, EmojiParser.parseToUnicode(String.valueOf(
|
||||
Objects.requireNonNull(binding.contentLayout.getEditText()).getText())), binding.markdownPreview, repository);
|
||||
|
||||
if(binding.markdown.getAdapter() == null) {
|
||||
Markdown.render(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown, repository);
|
||||
binding.markdownPreview.setVisibility(View.VISIBLE);
|
||||
binding.contentLayout.setVisibility(View.GONE);
|
||||
renderMd = false;
|
||||
}
|
||||
else {
|
||||
binding.markdownPreview.setVisibility(View.GONE);
|
||||
binding.contentLayout.setVisibility(View.VISIBLE);
|
||||
renderMd = true;
|
||||
}
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
renderMd = true;
|
||||
}
|
||||
else {
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
|
||||
renderMd = false;
|
||||
if(!renderMd) {
|
||||
|
||||
if(binding.markdown.getAdapter() == null) {
|
||||
Markdown.render(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown, repository);
|
||||
}
|
||||
|
||||
binding.contents.setVisibility(View.GONE);
|
||||
binding.markdownFrame.setVisibility(View.VISIBLE);
|
||||
|
||||
renderMd = true;
|
||||
}
|
||||
else {
|
||||
binding.markdownFrame.setVisibility(View.GONE);
|
||||
binding.contents.setVisibility(View.VISIBLE);
|
||||
|
||||
renderMd = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -123,6 +123,11 @@ public class WikiListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
|
||||
editWiki.setOnClickListener(v12 -> {
|
||||
|
||||
Intent intent = new Intent(ctx, WikiActivity.class);
|
||||
intent.putExtra("pageName", wikiPageMeta.getTitle());
|
||||
intent.putExtra("action", "edit");
|
||||
intent.putExtra(RepositoryContext.INTENT_EXTRA, ((RepoDetailActivity) itemView.getContext()).repository);
|
||||
ctx.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
@@ -152,6 +157,10 @@ public class WikiListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||
|
||||
TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
|
||||
avatar.setImageDrawable(drawable);
|
||||
|
||||
if(!((RepoDetailActivity) ctx).repository.getPermissions().isPush()) {
|
||||
wikiMenu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.mian.gitnex.viewmodels.WikiViewModel;
|
||||
|
||||
public class WikiFragment extends Fragment {
|
||||
|
||||
public static boolean resumeWiki = false;
|
||||
|
||||
private WikiViewModel wikiViewModel;
|
||||
private FragmentWikiBinding fragmentWikiBinding;
|
||||
private WikiListAdapter adapter;
|
||||
@@ -74,6 +76,16 @@ public class WikiFragment extends Fragment {
|
||||
return fragmentWikiBinding.getRoot();
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if(resumeWiki) {
|
||||
page = 1;
|
||||
fetchDataAsync(repository.getOwner(), repository.getName());
|
||||
resumeWiki = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String owner, String repo) {
|
||||
|
||||
wikiViewModel.getWiki(owner, repo, page, resultLimit, getContext(), fragmentWikiBinding).observe(getViewLifecycleOwner(), wikiListMain -> {
|
||||
|
||||
@@ -69,34 +69,118 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/markdown_frame"
|
||||
android:id="@+id/render_wiki"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/markdown_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/markdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.mian.gitnex.views.SyntaxHighlightedArea
|
||||
android:id="@+id/contents"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/create_wiki"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:visibility="gone">
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:boxBackgroundColor="?attr/inputBackgroundColor"
|
||||
android:textColorHint="?attr/hintColor"
|
||||
app:hintTextColor="?attr/hintColor"
|
||||
app:boxStrokeErrorColor="@color/darkRed"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:endIconMode="clear_text"
|
||||
app:endIconTint="?attr/iconsColor"
|
||||
android:hint="@string/newIssueTitle">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/wiki_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/inputTextColor"
|
||||
android:textColorHighlight="?attr/hintColor"
|
||||
android:textColorHint="?attr/hintColor"
|
||||
android:inputType="textCapSentences"
|
||||
android:singleLine="true"
|
||||
android:imeOptions="actionNext"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/content_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:boxBackgroundColor="?attr/inputBackgroundColor"
|
||||
android:textColorHint="?attr/hintColor"
|
||||
app:hintTextColor="?attr/hintColor"
|
||||
app:boxStrokeErrorColor="@color/darkRed"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/wiki_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="480dp"
|
||||
android:textColor="?attr/inputTextColor"
|
||||
android:textColorHighlight="?attr/hintColor"
|
||||
android:textColorHint="?attr/hintColor"
|
||||
android:gravity="top|start"
|
||||
android:singleLine="false"
|
||||
android:imeOptions="actionNext"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/markdown"
|
||||
android:id="@+id/markdown_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textIsSelectable="true"
|
||||
android:layout_marginTop="@dimen/dimen8dp"
|
||||
android:layout_marginBottom="@dimen/dimen8dp"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.mian.gitnex.views.SyntaxHighlightedArea
|
||||
android:id="@+id/contents"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
13
app/src/main/res/menu/save.xml
Normal file
13
app/src/main/res/menu/save.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/save"
|
||||
android:icon="@drawable/ic_save"
|
||||
android:title="@string/saveButton"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
</menu>
|
||||
@@ -772,6 +772,10 @@
|
||||
<string name="wikiAuthor"><![CDATA[<b>%1$s</b> updated %2$s]]></string>
|
||||
<string name="deleteWikiPageMessage">Do you really want to delete %s?</string>
|
||||
<string name="wikiPageDeleted">Wiki page deleted successfully</string>
|
||||
<string name="wikiPageNameAndContentError">Page name and page content can\'t be empty</string>
|
||||
<string name="createWikiPage">Create Wiki Page</string>
|
||||
<string name="wikiUpdated">Wiki page updated successfully</string>
|
||||
<string name="wikiCreated">Wiki page created successfully</string>
|
||||
|
||||
<!-- code editor -->
|
||||
<string name="sourcePosition" translatable="false">%1$d:%2$d</string>
|
||||
|
||||
Reference in New Issue
Block a user