Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cde97fe authored by stefan-niedermann's avatar stefan-niedermann
Browse files

#439 Allow Rendering of any markdown file

Create NoteReadonlyFragment to keep NotePreviewFragment clean
parent 21557336
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -24,6 +23,7 @@ import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.android.fragment.BaseNoteFragment;
import it.niedermann.owncloud.notes.android.fragment.NoteEditFragment;
import it.niedermann.owncloud.notes.android.fragment.NotePreviewFragment;
import it.niedermann.owncloud.notes.android.fragment.NoteReadonlyFragment;
import it.niedermann.owncloud.notes.model.Category;
import it.niedermann.owncloud.notes.model.CloudNote;
import it.niedermann.owncloud.notes.model.DBNote;
@@ -179,21 +179,17 @@ public class EditNoteActivity extends AppCompatActivity implements BaseNoteFragm
        Intent intent = getIntent();
        StringBuilder text = new StringBuilder();
        try {
            InputStream inputStream = getContentResolver().openInputStream(intent.getData());
            BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
            InputStream inputStream = getContentResolver().openInputStream(Objects.requireNonNull(intent.getData()));
            BufferedReader r = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
            String mLine;
            while ((mLine = r.readLine()) != null) {
                text.append(mLine).append('\n');
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.v("YEY", text.toString());


        fragment = NotePreviewFragment.newReadonlyInstance(text.toString());
        fragment = NoteReadonlyFragment.newInstance(text.toString());
        getSupportFragmentManager().beginTransaction().replace(android.R.id.content, fragment).commit();
    }

+1 −3
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo

    private static final String TAG = BaseNoteFragment.class.getSimpleName();

    private static final int MENU_ID_PIN = -1;
    protected static final int MENU_ID_PIN = -1;
    public static final String PARAM_NOTE_ID = "noteId";
    public static final String PARAM_ACCOUNT_ID = "accountId";
    public static final String PARAM_CONTENT = "content";
@@ -62,7 +62,6 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
    private NoteFragmentListener listener;

    boolean isNew = true;
    boolean isReadonly = false;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -93,7 +92,6 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
                        if (content == null) {
                            throw new IllegalArgumentException(PARAM_NOTE_ID + " is not given, argument " + PARAM_NEWNOTE + " is missing and " + PARAM_CONTENT + " is missing.");
                        } else {
                            isReadonly = true;
                            note = new DBNote(-1, -1, null, NoteUtil.generateNonEmptyNoteTitle(content, getContext()), content, false, "", null, DBStatus.VOID, -1, "");
                        }
                    } else {
+52 −62
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.core.view.ViewCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.yydcdut.markdown.MarkdownConfiguration;
import com.yydcdut.markdown.MarkdownProcessor;
import com.yydcdut.markdown.MarkdownTextView;
import com.yydcdut.markdown.syntax.text.TextFactory;
@@ -64,14 +63,6 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment {
    @BindView(R.id.single_note_content)
    MarkdownTextView noteContent;

    public static NotePreviewFragment newReadonlyInstance(String content) {
        NotePreviewFragment f = new NotePreviewFragment();
        Bundle b = new Bundle();
        b.putString(PARAM_CONTENT, content);
        f.setArguments(b);
        return f;
    }

    public static NotePreviewFragment newInstance(long accountId, long noteId) {
        NotePreviewFragment f = new NotePreviewFragment();
        Bundle b = new Bundle();
@@ -122,21 +113,9 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment {
        ButterKnife.bind(this, Objects.requireNonNull(getView()));
        markdownProcessor = new MarkdownProcessor(Objects.requireNonNull(getActivity()));
        markdownProcessor.factory(TextFactory.create());
        MarkdownConfiguration.Builder config = MarkDownUtil.getMarkDownConfiguration(noteContent.getContext())
                .setOnLinkClickCallback((view, link) -> {
                    if (NoteLinksUtils.isNoteLink(link)) {
                        long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link);
                        long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId);
                        Intent intent = new Intent(getActivity().getApplicationContext(), EditNoteActivity.class);
                        intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId);
                        startActivity(intent);
                    } else {
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
                        startActivity(browserIntent);
                    }
                });
        if (!isReadonly) {
            config.setOnTodoClickCallback((view, line, lineNumber) -> {
        markdownProcessor.config(
                MarkDownUtil.getMarkDownConfiguration(noteContent.getContext())
                        .setOnTodoClickCallback((view, line, lineNumber) -> {
                                    try {
                                        String[] lines = TextUtils.split(note.getContent(), "\\r?\\n");
                                        /*
@@ -175,9 +154,20 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment {
                                    }
                                    return line;
                                }
            );
                        )
                        .setOnLinkClickCallback((view, link) -> {
                            if (NoteLinksUtils.isNoteLink(link)) {
                                long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link);
                                long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId);
                                Intent intent = new Intent(getActivity().getApplicationContext(), EditNoteActivity.class);
                                intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId);
                                startActivity(intent);
                            } else {
                                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
                                startActivity(browserIntent);
                            }
        markdownProcessor.config(config.build());
                        })
                        .build());
        try {
            noteContent.setText(markdownProcessor.parse(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))));
            onResume();
+176 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.android.fragment;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Layout;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.yydcdut.markdown.MarkdownProcessor;
import com.yydcdut.markdown.MarkdownTextView;
import com.yydcdut.markdown.syntax.text.TextFactory;

import java.util.Objects;

import butterknife.BindView;
import butterknife.ButterKnife;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.android.activity.EditNoteActivity;
import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
import it.niedermann.owncloud.notes.util.DisplayUtils;
import it.niedermann.owncloud.notes.util.ICallback;
import it.niedermann.owncloud.notes.util.MarkDownUtil;
import it.niedermann.owncloud.notes.util.NoteLinksUtils;

public class NoteReadonlyFragment extends SearchableBaseNoteFragment {

    private MarkdownProcessor markdownProcessor;

    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout swipeRefreshLayout;

    @BindView(R.id.scrollView)
    ScrollView scrollView;

    @BindView(R.id.searchNext)
    FloatingActionButton searchNext;

    @BindView(R.id.searchPrev)
    FloatingActionButton searchPrev;

    @BindView(R.id.single_note_content)
    MarkdownTextView noteContent;

    public static NoteReadonlyFragment newInstance(String content) {
        NoteReadonlyFragment f = new NoteReadonlyFragment();
        Bundle b = new Bundle();
        b.putString(PARAM_CONTENT, content);
        f.setArguments(b);
        return f;
    }

    @Override
    public void onPrepareOptionsMenu(@NonNull Menu menu) {
        super.onPrepareOptionsMenu(menu);
        menu.findItem(R.id.menu_favorite).setVisible(false);
        menu.findItem(R.id.menu_edit).setVisible(false);
        menu.findItem(R.id.menu_preview).setVisible(false);
        menu.findItem(R.id.menu_cancel).setVisible(false);
        menu.findItem(R.id.menu_delete).setVisible(false);
        menu.findItem(R.id.menu_share).setVisible(false);
        menu.findItem(R.id.menu_move).setVisible(false);
        menu.findItem(R.id.menu_category).setVisible(false);
        menu.findItem(MENU_ID_PIN).setVisible(false);
    }

    @Override
    public ScrollView getScrollView() {
        return scrollView;
    }

    @Override
    protected FloatingActionButton getSearchNextButton() {
        return searchNext;
    }

    @Override
    protected FloatingActionButton getSearchPrevButton() {
        return searchPrev;
    }

    @Override
    protected Layout getLayout() {
        noteContent.onPreDraw();
        return noteContent.getLayout();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup
            container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_note_preview, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ButterKnife.bind(this, Objects.requireNonNull(getView()));
        markdownProcessor = new MarkdownProcessor(Objects.requireNonNull(getActivity()));
        markdownProcessor.factory(TextFactory.create());
        markdownProcessor.config(
                MarkDownUtil.getMarkDownConfiguration(noteContent.getContext())
                        .setOnLinkClickCallback((view, link) -> {
                            if (NoteLinksUtils.isNoteLink(link)) {
                                long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link);
                                long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId);
                                Intent intent = new Intent(getActivity().getApplicationContext(), EditNoteActivity.class);
                                intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId);
                                startActivity(intent);
                            } else {
                                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
                                startActivity(browserIntent);
                            }
                        })
                        .build());
        try {
            noteContent.setText(markdownProcessor.parse(note.getContent()));
            onResume();
        } catch (StringIndexOutOfBoundsException e) {
            // Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668
            Toast.makeText(noteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
        noteContent.setMovementMethod(LinkMovementMethod.getInstance());

        db = NoteSQLiteOpenHelper.getInstance(getActivity());
        swipeRefreshLayout.setEnabled(false);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(Objects.requireNonNull(getActivity()).getApplicationContext());
        noteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(sp));
        if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
            noteContent.setTypeface(Typeface.MONOSPACE);
        }
    }

    @Override
    public void onCloseNote() {
        // Do nothing
    }

    @Override
    protected void saveNote(@Nullable ICallback callback) {
        // Do nothing
    }

    @Override
    protected void colorWithText(String newText) {
        if (noteContent != null && ViewCompat.isAttachedToWindow(noteContent)) {
            noteContent.setText(markdownProcessor.parse(DisplayUtils.searchAndColor(getContent(), new SpannableString
                            (getContent()), newText, getResources().getColor(R.color.primary))),
                    TextView.BufferType.SPANNABLE);
        }
    }

    @Override
    protected String getContent() {
        return note.getContent();
    }
}