Loading app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/SingleNoteWidgetFactory.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget.DARK_THEME_KEY; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFactory { Loading Loading @@ -107,12 +108,12 @@ public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFa if (darkModeActive) { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content_dark); note_content.setOnClickFillInIntent(R.id.single_note_content_tv_dark, fillInIntent); note_content.setTextViewText(R.id.single_note_content_tv_dark, markdownProcessor.parse(note.getContent())); note_content.setTextViewText(R.id.single_note_content_tv_dark, parseCompat(markdownProcessor, note.getContent())); } else { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); note_content.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); note_content.setTextViewText(R.id.single_note_content_tv, markdownProcessor.parse(note.getContent())); note_content.setTextViewText(R.id.single_note_content_tv, parseCompat(markdownProcessor, note.getContent())); } return note_content; Loading app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java +11 −11 Original line number Diff line number Diff line Loading @@ -37,15 +37,18 @@ import it.niedermann.owncloud.notes.android.activity.EditNoteActivity; import it.niedermann.owncloud.notes.databinding.FragmentNotePreviewBinding; import it.niedermann.owncloud.notes.model.LoginStatus; import it.niedermann.owncloud.notes.persistence.NotesDatabase; import it.niedermann.owncloud.notes.util.DisplayUtils; import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.NoteLinksUtils; import it.niedermann.owncloud.notes.util.SSOUtil; import static it.niedermann.owncloud.notes.util.DisplayUtils.searchAndColor; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_MINUS; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_STAR; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_MINUS; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_STAR; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; import static it.niedermann.owncloud.notes.util.NoteLinksUtils.extractNoteRemoteId; import static it.niedermann.owncloud.notes.util.NoteLinksUtils.replaceNoteLinksWithDummyUrls; public class NotePreviewFragment extends SearchableBaseNoteFragment implements OnRefreshListener { Loading Loading @@ -138,7 +141,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O } changedText = TextUtils.join("\n", lines); binding.singleNoteContent.setText(markdownProcessor.parse(changedText)); binding.singleNoteContent.setText(parseCompat(markdownProcessor, changedText)); saveNote(null); } catch (IndexOutOfBoundsException e) { Toast.makeText(getActivity(), R.string.checkbox_could_not_be_toggled, Toast.LENGTH_SHORT).show(); Loading @@ -149,10 +152,8 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O ) .setOnLinkClickCallback((view, link) -> { if (NoteLinksUtils.isNoteLink(link)) { long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link); long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId); Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class); intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId); final Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class) .putExtra(EditNoteActivity.PARAM_NOTE_ID, db.getLocalIdByRemoteId(this.note.getAccountId(), extractNoteRemoteId(link))); startActivity(intent); } else { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); Loading @@ -161,11 +162,10 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O }) .build()); try { CharSequence parsedMarkdown = markdownProcessor.parse(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); binding.singleNoteContent.setText(parsedMarkdown); binding.singleNoteContent.setText(parseCompat(markdownProcessor, replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); } catch (StringIndexOutOfBoundsException e) { // Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668 binding.singleNoteContent.setText(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); binding.singleNoteContent.setText(replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); Toast.makeText(binding.singleNoteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show(); e.printStackTrace(); } Loading @@ -185,7 +185,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O @Override protected void colorWithText(String newText) { if (binding != null && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(markdownProcessor.parse(DisplayUtils.searchAndColor(getContent(), new SpannableString binding.singleNoteContent.setText(parseCompat(markdownProcessor, searchAndColor(getContent(), new SpannableString (getContent()), newText, getResources().getColor(R.color.primary))), TextView.BufferType.SPANNABLE); } Loading @@ -204,7 +204,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(requireContext()); db.getNoteServerSyncHelper().addCallbackPull(ssoAccount, () -> { note = db.getNote(note.getAccountId(), note.getId()); binding.singleNoteContent.setText(markdownProcessor.parse(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); binding.singleNoteContent.setText(parseCompat(markdownProcessor, replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); binding.swiperefreshlayout.setRefreshing(false); }); db.getNoteServerSyncHelper().scheduleSync(ssoAccount, false); Loading app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java +6 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import it.niedermann.owncloud.notes.util.DisplayUtils; import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.NoteLinksUtils; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; public class NoteReadonlyFragment extends SearchableBaseNoteFragment { private MarkdownProcessor markdownProcessor; Loading Loading @@ -114,10 +116,11 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment { }) .build()); try { binding.singleNoteContent.setText(markdownProcessor.parse(note.getContent())); binding.singleNoteContent.setText(parseCompat(markdownProcessor, note.getContent())); onResume(); } catch (StringIndexOutOfBoundsException e) { // Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668 binding.singleNoteContent.setText(note.getContent()); Toast.makeText(binding.singleNoteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show(); e.printStackTrace(); } Loading Loading @@ -145,8 +148,8 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment { @Override protected void colorWithText(String newText) { if (binding != null && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(markdownProcessor.parse(DisplayUtils.searchAndColor(getContent(), new SpannableString if ((binding != null) && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(parseCompat(markdownProcessor, DisplayUtils.searchAndColor(getContent(), new SpannableString (getContent()), newText, getResources().getColor(R.color.primary))), TextView.BufferType.SPANNABLE); } Loading app/src/main/java/it/niedermann/owncloud/notes/util/MarkDownUtil.java +36 −0 Original line number Diff line number Diff line Loading @@ -3,12 +3,15 @@ package it.niedermann.owncloud.notes.util; import android.content.Context; import android.graphics.Color; import android.text.Spanned; import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import com.yydcdut.markdown.MarkdownConfiguration; import com.yydcdut.markdown.MarkdownConfiguration.Builder; import com.yydcdut.markdown.MarkdownProcessor; import com.yydcdut.markdown.span.MDImageSpan; import com.yydcdut.markdown.theme.ThemeDefault; import com.yydcdut.markdown.theme.ThemeSonsOfObsidian; Loading @@ -22,6 +25,8 @@ import it.niedermann.owncloud.notes.R; @SuppressWarnings("WeakerAccess") public class MarkDownUtil { private static final String TAG = MarkDownUtil.class.getCanonicalName(); public static final String CHECKBOX_UNCHECKED_MINUS = "- [ ]"; public static final String CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE = CHECKBOX_UNCHECKED_MINUS + " "; public static final String CHECKBOX_UNCHECKED_STAR = "* [ ]"; Loading @@ -29,6 +34,11 @@ public class MarkDownUtil { public static final String CHECKBOX_CHECKED_MINUS = "- [x]"; public static final String CHECKBOX_CHECKED_STAR = "* [x]"; private static final String MD_IMAGE_WITH_EMPTY_DESCRIPTION = "; } /** * This is a compatibility-method that provides workarounds for several bugs in RxMarkdown * * https://github.com/stefan-niedermann/nextcloud-notes/issues/772 * * @param markdownProcessor RxMarkdown MarkdownProcessor instance * @param text CharSequence that should be parsed * @return the processed text but with several workarounds for Bugs in RxMarkdown */ @NonNull public static CharSequence parseCompat(@NonNull final MarkdownProcessor markdownProcessor, CharSequence text) { if (TextUtils.isEmpty(text)) { return ""; } Log.v(TAG, "parseCompat - Original: \"" + text + "\""); while (TextUtils.indexOf(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION) >= 0) { text = TextUtils.replace(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION_ARRAY, MD_IMAGE_WITH_SPACE_DESCRIPTION_ARRAY); } Log.v(TAG, "parseCompat - Replaced empty image descriptions: \"" + text + "\""); return markdownProcessor.parse(text); } public static boolean containsImageSpan(@NonNull CharSequence text) { return ((Spanned) text).getSpans(0, text.length(), MDImageSpan.class).length > 0; } Loading Loading
app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/SingleNoteWidgetFactory.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget.DARK_THEME_KEY; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFactory { Loading Loading @@ -107,12 +108,12 @@ public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFa if (darkModeActive) { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content_dark); note_content.setOnClickFillInIntent(R.id.single_note_content_tv_dark, fillInIntent); note_content.setTextViewText(R.id.single_note_content_tv_dark, markdownProcessor.parse(note.getContent())); note_content.setTextViewText(R.id.single_note_content_tv_dark, parseCompat(markdownProcessor, note.getContent())); } else { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); note_content.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); note_content.setTextViewText(R.id.single_note_content_tv, markdownProcessor.parse(note.getContent())); note_content.setTextViewText(R.id.single_note_content_tv, parseCompat(markdownProcessor, note.getContent())); } return note_content; Loading
app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java +11 −11 Original line number Diff line number Diff line Loading @@ -37,15 +37,18 @@ import it.niedermann.owncloud.notes.android.activity.EditNoteActivity; import it.niedermann.owncloud.notes.databinding.FragmentNotePreviewBinding; import it.niedermann.owncloud.notes.model.LoginStatus; import it.niedermann.owncloud.notes.persistence.NotesDatabase; import it.niedermann.owncloud.notes.util.DisplayUtils; import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.NoteLinksUtils; import it.niedermann.owncloud.notes.util.SSOUtil; import static it.niedermann.owncloud.notes.util.DisplayUtils.searchAndColor; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_MINUS; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_STAR; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_MINUS; import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_STAR; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; import static it.niedermann.owncloud.notes.util.NoteLinksUtils.extractNoteRemoteId; import static it.niedermann.owncloud.notes.util.NoteLinksUtils.replaceNoteLinksWithDummyUrls; public class NotePreviewFragment extends SearchableBaseNoteFragment implements OnRefreshListener { Loading Loading @@ -138,7 +141,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O } changedText = TextUtils.join("\n", lines); binding.singleNoteContent.setText(markdownProcessor.parse(changedText)); binding.singleNoteContent.setText(parseCompat(markdownProcessor, changedText)); saveNote(null); } catch (IndexOutOfBoundsException e) { Toast.makeText(getActivity(), R.string.checkbox_could_not_be_toggled, Toast.LENGTH_SHORT).show(); Loading @@ -149,10 +152,8 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O ) .setOnLinkClickCallback((view, link) -> { if (NoteLinksUtils.isNoteLink(link)) { long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link); long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId); Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class); intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId); final Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class) .putExtra(EditNoteActivity.PARAM_NOTE_ID, db.getLocalIdByRemoteId(this.note.getAccountId(), extractNoteRemoteId(link))); startActivity(intent); } else { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); Loading @@ -161,11 +162,10 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O }) .build()); try { CharSequence parsedMarkdown = markdownProcessor.parse(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); binding.singleNoteContent.setText(parsedMarkdown); binding.singleNoteContent.setText(parseCompat(markdownProcessor, replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); } catch (StringIndexOutOfBoundsException e) { // Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668 binding.singleNoteContent.setText(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); binding.singleNoteContent.setText(replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId()))); Toast.makeText(binding.singleNoteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show(); e.printStackTrace(); } Loading @@ -185,7 +185,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O @Override protected void colorWithText(String newText) { if (binding != null && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(markdownProcessor.parse(DisplayUtils.searchAndColor(getContent(), new SpannableString binding.singleNoteContent.setText(parseCompat(markdownProcessor, searchAndColor(getContent(), new SpannableString (getContent()), newText, getResources().getColor(R.color.primary))), TextView.BufferType.SPANNABLE); } Loading @@ -204,7 +204,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(requireContext()); db.getNoteServerSyncHelper().addCallbackPull(ssoAccount, () -> { note = db.getNote(note.getAccountId(), note.getId()); binding.singleNoteContent.setText(markdownProcessor.parse(NoteLinksUtils.replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); binding.singleNoteContent.setText(parseCompat(markdownProcessor, replaceNoteLinksWithDummyUrls(note.getContent(), db.getRemoteIds(note.getAccountId())))); binding.swiperefreshlayout.setRefreshing(false); }); db.getNoteServerSyncHelper().scheduleSync(ssoAccount, false); Loading
app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java +6 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import it.niedermann.owncloud.notes.util.DisplayUtils; import it.niedermann.owncloud.notes.util.MarkDownUtil; import it.niedermann.owncloud.notes.util.NoteLinksUtils; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; public class NoteReadonlyFragment extends SearchableBaseNoteFragment { private MarkdownProcessor markdownProcessor; Loading Loading @@ -114,10 +116,11 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment { }) .build()); try { binding.singleNoteContent.setText(markdownProcessor.parse(note.getContent())); binding.singleNoteContent.setText(parseCompat(markdownProcessor, note.getContent())); onResume(); } catch (StringIndexOutOfBoundsException e) { // Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668 binding.singleNoteContent.setText(note.getContent()); Toast.makeText(binding.singleNoteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show(); e.printStackTrace(); } Loading Loading @@ -145,8 +148,8 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment { @Override protected void colorWithText(String newText) { if (binding != null && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(markdownProcessor.parse(DisplayUtils.searchAndColor(getContent(), new SpannableString if ((binding != null) && ViewCompat.isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.setText(parseCompat(markdownProcessor, DisplayUtils.searchAndColor(getContent(), new SpannableString (getContent()), newText, getResources().getColor(R.color.primary))), TextView.BufferType.SPANNABLE); } Loading
app/src/main/java/it/niedermann/owncloud/notes/util/MarkDownUtil.java +36 −0 Original line number Diff line number Diff line Loading @@ -3,12 +3,15 @@ package it.niedermann.owncloud.notes.util; import android.content.Context; import android.graphics.Color; import android.text.Spanned; import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import com.yydcdut.markdown.MarkdownConfiguration; import com.yydcdut.markdown.MarkdownConfiguration.Builder; import com.yydcdut.markdown.MarkdownProcessor; import com.yydcdut.markdown.span.MDImageSpan; import com.yydcdut.markdown.theme.ThemeDefault; import com.yydcdut.markdown.theme.ThemeSonsOfObsidian; Loading @@ -22,6 +25,8 @@ import it.niedermann.owncloud.notes.R; @SuppressWarnings("WeakerAccess") public class MarkDownUtil { private static final String TAG = MarkDownUtil.class.getCanonicalName(); public static final String CHECKBOX_UNCHECKED_MINUS = "- [ ]"; public static final String CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE = CHECKBOX_UNCHECKED_MINUS + " "; public static final String CHECKBOX_UNCHECKED_STAR = "* [ ]"; Loading @@ -29,6 +34,11 @@ public class MarkDownUtil { public static final String CHECKBOX_CHECKED_MINUS = "- [x]"; public static final String CHECKBOX_CHECKED_STAR = "* [x]"; private static final String MD_IMAGE_WITH_EMPTY_DESCRIPTION = "; } /** * This is a compatibility-method that provides workarounds for several bugs in RxMarkdown * * https://github.com/stefan-niedermann/nextcloud-notes/issues/772 * * @param markdownProcessor RxMarkdown MarkdownProcessor instance * @param text CharSequence that should be parsed * @return the processed text but with several workarounds for Bugs in RxMarkdown */ @NonNull public static CharSequence parseCompat(@NonNull final MarkdownProcessor markdownProcessor, CharSequence text) { if (TextUtils.isEmpty(text)) { return ""; } Log.v(TAG, "parseCompat - Original: \"" + text + "\""); while (TextUtils.indexOf(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION) >= 0) { text = TextUtils.replace(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION_ARRAY, MD_IMAGE_WITH_SPACE_DESCRIPTION_ARRAY); } Log.v(TAG, "parseCompat - Replaced empty image descriptions: \"" + text + "\""); return markdownProcessor.parse(text); } public static boolean containsImageSpan(@NonNull CharSequence text) { return ((Spanned) text).getSpans(0, text.length(), MDImageSpan.class).length > 0; } Loading