500 lines
14 KiB
Java
500 lines
14 KiB
Java
package org.mian.gitnex.activities;
|
|
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.text.method.ScrollingMovementMethod;
|
|
import android.view.Menu;
|
|
import android.view.MenuInflater;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import androidx.annotation.NonNull;
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
import com.vdurmont.emoji.EmojiParser;
|
|
import java.util.Objects;
|
|
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.BottomSheetWikiFragment;
|
|
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 org.mian.gitnex.structs.BottomSheetListener;
|
|
import retrofit2.Call;
|
|
import retrofit2.Callback;
|
|
import retrofit2.Response;
|
|
|
|
/**
|
|
* @author M M Arif
|
|
*/
|
|
public class WikiActivity extends BaseActivity implements BottomSheetListener {
|
|
|
|
private ActivityWikiBinding binding;
|
|
private String pageName;
|
|
private String action;
|
|
private RepositoryContext repository;
|
|
private boolean renderMd = true;
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
binding = ActivityWikiBinding.inflate(getLayoutInflater());
|
|
repository = RepositoryContext.fromIntent(getIntent());
|
|
|
|
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);
|
|
|
|
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() {
|
|
|
|
Call<WikiPage> call =
|
|
RetrofitClient.getApiInterface(ctx)
|
|
.repoGetWikiPage(repository.getOwner(), repository.getName(), pageName);
|
|
|
|
call.enqueue(
|
|
new Callback<>() {
|
|
|
|
@Override
|
|
public void onResponse(
|
|
@NonNull Call<WikiPage> call,
|
|
@NonNull retrofit2.Response<WikiPage> response) {
|
|
|
|
if (response.isSuccessful()) {
|
|
if (response.code() == 200) {
|
|
|
|
WikiPage wikiPage = response.body();
|
|
|
|
runOnUiThread(
|
|
() -> {
|
|
assert wikiPage != null;
|
|
String pageContents =
|
|
AppUtil.decodeBase64(
|
|
wikiPage.getContentBase64());
|
|
binding.contents.setContent(pageContents, "md");
|
|
|
|
if (renderMd) {
|
|
Markdown.render(
|
|
ctx,
|
|
EmojiParser.parseToUnicode(pageContents),
|
|
binding.markdown,
|
|
repository);
|
|
|
|
binding.markdownFrame.setVisibility(View.VISIBLE);
|
|
binding.contents.setVisibility(View.GONE);
|
|
} else {
|
|
binding.markdownFrame.setVisibility(View.GONE);
|
|
binding.contents.setVisibility(View.VISIBLE);
|
|
}
|
|
|
|
if (action.equalsIgnoreCase("edit")) {
|
|
binding.wikiContent.setText(pageContents);
|
|
}
|
|
});
|
|
} 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)));
|
|
}
|
|
}
|
|
|
|
binding.progressBar.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(@NonNull Call<WikiPage> call, @NonNull Throwable t) {
|
|
|
|
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError));
|
|
}
|
|
});
|
|
}
|
|
|
|
private void deleteWiki(final String owner, final String repo, final String pageName) {
|
|
|
|
MaterialAlertDialogBuilder materialAlertDialogBuilder =
|
|
new MaterialAlertDialogBuilder(ctx)
|
|
.setTitle(
|
|
String.format(ctx.getString(R.string.deleteGenericTitle), pageName))
|
|
.setMessage(ctx.getString(R.string.deleteWikiPageMessage, pageName))
|
|
.setNeutralButton(R.string.cancelButton, null)
|
|
.setPositiveButton(
|
|
R.string.menuDeleteText,
|
|
(dialog, whichButton) ->
|
|
RetrofitClient.getApiInterface(ctx)
|
|
.repoDeleteWikiPage(owner, repo, pageName)
|
|
.enqueue(
|
|
new Callback<>() {
|
|
|
|
@Override
|
|
public void onResponse(
|
|
@NonNull Call<Void> call,
|
|
@NonNull Response<Void>
|
|
response) {
|
|
|
|
if (response.isSuccessful()) {
|
|
Toasty.success(
|
|
ctx,
|
|
getString(
|
|
R.string
|
|
.wikiPageDeleted));
|
|
WikiFragment.resumeWiki = true;
|
|
finish();
|
|
} else if (response.code() == 403) {
|
|
Toasty.error(
|
|
ctx,
|
|
ctx.getString(
|
|
R.string
|
|
.authorizeError));
|
|
} else {
|
|
Toasty.error(
|
|
ctx,
|
|
ctx.getString(
|
|
R.string
|
|
.genericError));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(
|
|
@NonNull Call<Void> call,
|
|
@NonNull Throwable t) {
|
|
|
|
Toasty.error(
|
|
ctx,
|
|
ctx.getString(
|
|
R.string
|
|
.genericError));
|
|
}
|
|
}));
|
|
|
|
materialAlertDialogBuilder.create().show();
|
|
}
|
|
|
|
@Override
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|
MenuInflater inflater = getMenuInflater();
|
|
inflater.inflate(R.menu.markdown_switcher, menu);
|
|
if (action.equalsIgnoreCase("edit") || action.equalsIgnoreCase("add")) {
|
|
inflater.inflate(R.menu.save, menu);
|
|
} else {
|
|
if (repository.getPermissions().isPush()) {
|
|
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onButtonClicked(String text) {
|
|
switch (text) {
|
|
case "editWiki":
|
|
Intent intent = new Intent(ctx, WikiActivity.class);
|
|
intent.putExtra("pageName", pageName);
|
|
intent.putExtra("action", "edit");
|
|
intent.putExtra(RepositoryContext.INTENT_EXTRA, repository);
|
|
ctx.startActivity(intent);
|
|
finish();
|
|
break;
|
|
case "delWiki":
|
|
deleteWiki(repository.getOwner(), repository.getName(), pageName);
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
int id = item.getItemId();
|
|
|
|
if (id == android.R.id.home) {
|
|
|
|
finish();
|
|
return true;
|
|
} else if (id == R.id.genericMenu) {
|
|
|
|
BottomSheetWikiFragment bottomSheet = new BottomSheetWikiFragment();
|
|
bottomSheet.show(getSupportFragmentManager(), "wikiBottomSheet");
|
|
return true;
|
|
} else if (id == R.id.save) {
|
|
|
|
processWiki();
|
|
return true;
|
|
} else if (id == R.id.markdown) {
|
|
|
|
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);
|
|
|
|
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;
|
|
}
|
|
} else {
|
|
|
|
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;
|
|
} else {
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
}
|
|
}
|