Add markdown support to notifications
This commit is contained in:
119
app/src/main/java/com/github/gotify/MarkwonFactory.java
Normal file
119
app/src/main/java/com/github/gotify/MarkwonFactory.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.BulletSpan;
|
||||
import android.text.style.QuoteSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.MarkwonSpansFactory;
|
||||
import io.noties.markwon.MarkwonVisitor;
|
||||
import io.noties.markwon.core.CorePlugin;
|
||||
import io.noties.markwon.core.CoreProps;
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
||||
import io.noties.markwon.ext.tables.TableAwareMovementMethod;
|
||||
import io.noties.markwon.ext.tables.TablePlugin;
|
||||
import io.noties.markwon.image.picasso.PicassoImagesPlugin;
|
||||
import io.noties.markwon.movement.MovementMethodPlugin;
|
||||
import java.util.Collections;
|
||||
import org.commonmark.ext.gfm.tables.TableCell;
|
||||
import org.commonmark.ext.gfm.tables.TablesExtension;
|
||||
import org.commonmark.node.BlockQuote;
|
||||
import org.commonmark.node.Code;
|
||||
import org.commonmark.node.Emphasis;
|
||||
import org.commonmark.node.Heading;
|
||||
import org.commonmark.node.Link;
|
||||
import org.commonmark.node.ListItem;
|
||||
import org.commonmark.node.StrongEmphasis;
|
||||
import org.commonmark.parser.Parser;
|
||||
|
||||
public class MarkwonFactory {
|
||||
public static Markwon createForMessage(Context context, Picasso picasso) {
|
||||
return Markwon.builder(context)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
|
||||
.usePlugin(PicassoImagesPlugin.create(picasso))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(TablePlugin.create(context))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Markwon createForNotification(Context context, Picasso picasso) {
|
||||
final float[] headingSizes = {
|
||||
2.F, 1.5F, 1.17F, 1.F, .83F, .67F,
|
||||
};
|
||||
|
||||
final int bulletGapWidth =
|
||||
(int) (8 * context.getResources().getDisplayMetrics().density + 0.5F);
|
||||
|
||||
return Markwon.builder(context)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(PicassoImagesPlugin.create(picasso))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(
|
||||
new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureSpansFactory(
|
||||
@NonNull MarkwonSpansFactory.Builder builder) {
|
||||
builder.setFactory(
|
||||
Heading.class,
|
||||
(configuration, props) ->
|
||||
new Object[] {
|
||||
new RelativeSizeSpan(
|
||||
headingSizes[
|
||||
CoreProps.HEADING_LEVEL
|
||||
.require(
|
||||
props)
|
||||
- 1]),
|
||||
new StyleSpan(Typeface.BOLD)
|
||||
})
|
||||
.setFactory(
|
||||
Emphasis.class,
|
||||
(configuration, props) ->
|
||||
new StyleSpan(Typeface.ITALIC))
|
||||
.setFactory(
|
||||
StrongEmphasis.class,
|
||||
(configuration, props) ->
|
||||
new StyleSpan(Typeface.BOLD))
|
||||
.setFactory(
|
||||
BlockQuote.class,
|
||||
(configuration, props) -> new QuoteSpan())
|
||||
.setFactory(
|
||||
Code.class,
|
||||
(configuration, props) ->
|
||||
new Object[] {
|
||||
new BackgroundColorSpan(Color.LTGRAY),
|
||||
new TypefaceSpan("monospace")
|
||||
})
|
||||
.setFactory(
|
||||
ListItem.class,
|
||||
(configuration, props) ->
|
||||
new BulletSpan(bulletGapWidth))
|
||||
.setFactory(Link.class, ((configuration, props) -> null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureParser(@NonNull Parser.Builder builder) {
|
||||
builder.extensions(Collections.singleton(TablesExtension.create()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||
builder.on(
|
||||
TableCell.class,
|
||||
(visitor, node) -> {
|
||||
visitor.visitChildren(node);
|
||||
visitor.builder().append(' ');
|
||||
});
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,15 @@ public final class Extras {
|
||||
private Extras() {}
|
||||
|
||||
public static boolean useMarkdown(Message message) {
|
||||
if (message.getExtras() == null) {
|
||||
return useMarkdown(message.getExtras());
|
||||
}
|
||||
|
||||
public static boolean useMarkdown(Map<String, Object> extras) {
|
||||
if (extras == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object display = message.getExtras().get("client::display");
|
||||
Object display = extras.get("client::display");
|
||||
if (!(display instanceof Map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import com.github.gotify.MarkwonFactory;
|
||||
import com.github.gotify.R;
|
||||
import com.github.gotify.Settings;
|
||||
import com.github.gotify.Utils;
|
||||
@@ -25,12 +26,6 @@ import com.github.gotify.client.model.Message;
|
||||
import com.github.gotify.messages.provider.MessageWithImage;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.core.CorePlugin;
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
||||
import io.noties.markwon.ext.tables.TableAwareMovementMethod;
|
||||
import io.noties.markwon.ext.tables.TablePlugin;
|
||||
import io.noties.markwon.image.picasso.PicassoImagesPlugin;
|
||||
import io.noties.markwon.movement.MovementMethodPlugin;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -61,14 +56,7 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
|
||||
this.items = items;
|
||||
this.delete = delete;
|
||||
|
||||
this.markwon =
|
||||
Markwon.builder(context)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
|
||||
.usePlugin(PicassoImagesPlugin.create(picasso))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(TablePlugin.create(context))
|
||||
.build();
|
||||
this.markwon = MarkwonFactory.createForMessage(context, picasso);
|
||||
|
||||
TIME_FORMAT_RELATIVE =
|
||||
context.getResources().getString(R.string.time_format_value_relative);
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.github.gotify.MarkwonFactory;
|
||||
import com.github.gotify.MissedMessageUtil;
|
||||
import com.github.gotify.NotificationSupport;
|
||||
import com.github.gotify.R;
|
||||
@@ -31,6 +32,7 @@ import com.github.gotify.log.UncaughtExceptionHandler;
|
||||
import com.github.gotify.messages.Extras;
|
||||
import com.github.gotify.messages.MessagesActivity;
|
||||
import com.github.gotify.picasso.PicassoHandler;
|
||||
import io.noties.markwon.Markwon;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
@@ -51,6 +53,7 @@ public class WebSocketService extends Service {
|
||||
private MissedMessageUtil missingMessageUtil;
|
||||
|
||||
private PicassoHandler picassoHandler;
|
||||
private Markwon markwon;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@@ -61,6 +64,7 @@ public class WebSocketService extends Service {
|
||||
missingMessageUtil = new MissedMessageUtil(client.createService(MessageApi.class));
|
||||
Log.i("Create " + getClass().getSimpleName());
|
||||
picassoHandler = new PicassoHandler(this, settings);
|
||||
markwon = MarkwonFactory.createForNotification(this, picassoHandler.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -297,13 +301,19 @@ public class WebSocketService extends Service {
|
||||
.setTicker(getString(R.string.app_name) + " - " + title)
|
||||
.setGroup(NotificationSupport.Group.MESSAGES)
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
|
||||
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
|
||||
.setLights(Color.CYAN, 1000, 5000)
|
||||
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
|
||||
.setContentIntent(contentIntent);
|
||||
|
||||
CharSequence formattedMessage = message;
|
||||
if (Extras.useMarkdown(extras)) {
|
||||
formattedMessage = markwon.toMarkdown(message);
|
||||
message = formattedMessage.toString();
|
||||
}
|
||||
b.setContentText(message);
|
||||
b.setStyle(new NotificationCompat.BigTextStyle().bigText(formattedMessage));
|
||||
|
||||
NotificationManager notificationManager =
|
||||
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(Utils.longToInt(id), b.build());
|
||||
|
||||
Reference in New Issue
Block a user