diff --git a/app/build.gradle b/app/build.gradle index d29a1f43..491be262 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java index e8870c24..62da9bfa 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java @@ -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; } } diff --git a/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java b/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java index 81ec775e..e9d7e5af 100644 --- a/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/WikiActivity.java @@ -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 call = RetrofitClient + .getApiInterface(ctx) + .repoCreateWikiPage(repository.getOwner(), repository.getName(), createWikiPageOptions); + + call.enqueue(new Callback<>() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response 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 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 call = RetrofitClient + .getApiInterface(ctx) + .repoEditWikiPage(repository.getOwner(), repository.getName(), pageName, createWikiPageOptions); + + call.enqueue(new Callback<>() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response 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 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; diff --git a/app/src/main/java/org/mian/gitnex/adapters/WikiListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/WikiListAdapter.java index 7ee47184..f1186df2 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/WikiListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/WikiListAdapter.java @@ -123,6 +123,11 @@ public class WikiListAdapter extends RecyclerView.Adapter { + 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 { diff --git a/app/src/main/res/layout/activity_wiki.xml b/app/src/main/res/layout/activity_wiki.xml index d3995d21..097dce6a 100644 --- a/app/src/main/res/layout/activity_wiki.xml +++ b/app/src/main/res/layout/activity_wiki.xml @@ -69,34 +69,118 @@ android:orientation="vertical"> + + + + + + + + + + + + + android:orientation="vertical"> + + + + + + + + + + + + - - diff --git a/app/src/main/res/menu/save.xml b/app/src/main/res/menu/save.xml new file mode 100644 index 00000000..0413f872 --- /dev/null +++ b/app/src/main/res/menu/save.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 72b3e812..cf5237a0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -772,6 +772,10 @@ %1$s updated %2$s]]> Do you really want to delete %s? Wiki page deleted successfully + Page name and page content can\'t be empty + Create Wiki Page + Wiki page updated successfully + Wiki page created successfully %1$d:%2$d