Rewrite root directory files to Kotlin
This commit is contained in:
@@ -1,130 +0,0 @@
|
||||
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 androidx.core.content.ContextCompat;
|
||||
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.core.MarkwonTheme;
|
||||
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))
|
||||
.usePlugin(
|
||||
new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
||||
builder.linkColor(
|
||||
ContextCompat.getColor(context, R.color.hyperLink))
|
||||
.isLinkUnderlined(true);
|
||||
}
|
||||
})
|
||||
.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();
|
||||
}
|
||||
}
|
||||
96
app/src/main/java/com/github/gotify/MarkwonFactory.kt
Normal file
96
app/src/main/java/com/github/gotify/MarkwonFactory.kt
Normal file
@@ -0,0 +1,96 @@
|
||||
package com.github.gotify
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.text.style.*
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.squareup.picasso.Picasso
|
||||
import io.noties.markwon.*
|
||||
import io.noties.markwon.core.CorePlugin
|
||||
import io.noties.markwon.core.CoreProps
|
||||
import io.noties.markwon.core.MarkwonTheme
|
||||
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 org.commonmark.ext.gfm.tables.TableCell
|
||||
import org.commonmark.ext.gfm.tables.TablesExtension
|
||||
import org.commonmark.node.*
|
||||
import org.commonmark.parser.Parser
|
||||
|
||||
object MarkwonFactory {
|
||||
fun createForMessage(context: Context, picasso: Picasso): Markwon {
|
||||
return Markwon.builder(context)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
|
||||
.usePlugin(PicassoImagesPlugin.create(picasso))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(TablePlugin.create(context))
|
||||
.usePlugin(
|
||||
object : AbstractMarkwonPlugin() {
|
||||
override fun configureTheme(builder: MarkwonTheme.Builder) {
|
||||
builder.linkColor(ContextCompat.getColor(context, R.color.hyperLink))
|
||||
.isLinkUnderlined(true)
|
||||
}
|
||||
})
|
||||
.build()
|
||||
}
|
||||
|
||||
fun createForNotification(context: Context, picasso: Picasso): Markwon {
|
||||
val headingSizes = floatArrayOf(
|
||||
2f, 1.5f, 1.17f, 1f, .83f, .67f
|
||||
)
|
||||
val bulletGapWidth = (8 * context.resources.displayMetrics.density + 0.5f).toInt()
|
||||
|
||||
return Markwon.builder(context)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.usePlugin(PicassoImagesPlugin.create(picasso))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(
|
||||
object : AbstractMarkwonPlugin() {
|
||||
override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) {
|
||||
builder.setFactory(Heading::class.java) { _, props: RenderProps? ->
|
||||
arrayOf<Any>(
|
||||
RelativeSizeSpan(
|
||||
headingSizes[CoreProps.HEADING_LEVEL.require(props!!) - 1]
|
||||
),
|
||||
StyleSpan(Typeface.BOLD)
|
||||
)
|
||||
}
|
||||
.setFactory(Emphasis::class.java) { _, _ ->
|
||||
StyleSpan(Typeface.ITALIC)
|
||||
}
|
||||
.setFactory(StrongEmphasis::class.java) { _, _ ->
|
||||
StyleSpan(Typeface.BOLD)
|
||||
}
|
||||
.setFactory(BlockQuote::class.java) { _, _ -> QuoteSpan() }
|
||||
.setFactory(Code::class.java) { _, _ ->
|
||||
arrayOf<Any>(
|
||||
BackgroundColorSpan(Color.LTGRAY),
|
||||
TypefaceSpan("monospace")
|
||||
)
|
||||
}
|
||||
.setFactory(ListItem::class.java) { _, _ ->
|
||||
BulletSpan(bulletGapWidth)
|
||||
}
|
||||
.setFactory(Link::class.java) { _, _ -> null }
|
||||
}
|
||||
|
||||
override fun configureParser(builder: Parser.Builder) {
|
||||
builder.extensions(setOf(TablesExtension.create()))
|
||||
}
|
||||
|
||||
override fun configureVisitor(builder: MarkwonVisitor.Builder) {
|
||||
builder.on(
|
||||
TableCell::class.java
|
||||
) { visitor: MarkwonVisitor, node: TableCell? ->
|
||||
visitor.visitChildren(node!!)
|
||||
visitor.builder().append(' ')
|
||||
}
|
||||
}
|
||||
})
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import com.github.gotify.api.Api;
|
||||
import com.github.gotify.api.ApiException;
|
||||
import com.github.gotify.api.Callback;
|
||||
import com.github.gotify.client.api.MessageApi;
|
||||
import com.github.gotify.client.model.Message;
|
||||
import com.github.gotify.client.model.PagedMessages;
|
||||
import com.github.gotify.log.Log;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.gotify.api.Callback.call;
|
||||
|
||||
public class MissedMessageUtil {
|
||||
static final long NO_MESSAGES = 0;
|
||||
|
||||
private final MessageApi api;
|
||||
|
||||
public MissedMessageUtil(MessageApi api) {
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
public void lastReceivedMessage(Callback.SuccessCallback<Long> successCallback) {
|
||||
api.getMessages(1, 0L)
|
||||
.enqueue(
|
||||
call(
|
||||
(messages) -> {
|
||||
if (messages.getMessages().size() == 1) {
|
||||
successCallback.onSuccess(
|
||||
messages.getMessages().get(0).getId());
|
||||
} else {
|
||||
successCallback.onSuccess(NO_MESSAGES);
|
||||
}
|
||||
},
|
||||
(e) -> {}));
|
||||
}
|
||||
|
||||
public List<Message> missingMessages(long till) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
try {
|
||||
|
||||
Long since = null;
|
||||
while (true) {
|
||||
PagedMessages pagedMessages = Api.execute(api.getMessages(10, since));
|
||||
List<Message> messages = pagedMessages.getMessages();
|
||||
List<Message> filtered = filter(messages, till);
|
||||
result.addAll(filtered);
|
||||
if (messages.size() != filtered.size()
|
||||
|| messages.size() == 0
|
||||
|| pagedMessages.getPaging().getNext() == null) {
|
||||
break;
|
||||
}
|
||||
since = pagedMessages.getPaging().getSince();
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
Log.e("cannot retrieve missing messages", e);
|
||||
}
|
||||
Collections.reverse(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Message> filter(List<Message> messages, long till) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
|
||||
for (Message message : messages) {
|
||||
if (message.getId() > till) {
|
||||
result.add(message);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
63
app/src/main/java/com/github/gotify/MissedMessageUtil.kt
Normal file
63
app/src/main/java/com/github/gotify/MissedMessageUtil.kt
Normal file
@@ -0,0 +1,63 @@
|
||||
package com.github.gotify
|
||||
|
||||
import com.github.gotify.api.Api
|
||||
import com.github.gotify.api.ApiException
|
||||
import com.github.gotify.api.Callback
|
||||
import com.github.gotify.api.Callback.SuccessCallback
|
||||
import com.github.gotify.client.api.MessageApi
|
||||
import com.github.gotify.client.model.Message
|
||||
import com.github.gotify.client.model.PagedMessages
|
||||
import com.github.gotify.log.Log
|
||||
|
||||
class MissedMessageUtil(private val api: MessageApi) {
|
||||
fun lastReceivedMessage(successCallback: SuccessCallback<Long?>) {
|
||||
api.getMessages(1, 0L).enqueue(
|
||||
Callback.call({ messages: PagedMessages? ->
|
||||
if (messages!!.messages.size == 1) {
|
||||
successCallback.onSuccess(messages.messages[0].id)
|
||||
} else {
|
||||
successCallback.onSuccess(NO_MESSAGES)
|
||||
}
|
||||
}
|
||||
) {}
|
||||
)
|
||||
}
|
||||
|
||||
fun missingMessages(till: Long): List<Message?> {
|
||||
val result = mutableListOf<Message?>()
|
||||
try {
|
||||
var since: Long? = null
|
||||
while (true) {
|
||||
val pagedMessages = Api.execute(api.getMessages(10, since))
|
||||
val messages = pagedMessages!!.messages
|
||||
val filtered = filter(messages, till)
|
||||
result.addAll(filtered)
|
||||
if (messages.size != filtered.size
|
||||
|| messages.size == 0
|
||||
|| pagedMessages.paging.next == null) {
|
||||
break
|
||||
}
|
||||
since = pagedMessages.paging.since
|
||||
}
|
||||
} catch (e: ApiException) {
|
||||
Log.e("cannot retrieve missing messages", e)
|
||||
}
|
||||
return result.reversed()
|
||||
}
|
||||
|
||||
private fun filter(messages: List<Message>, till: Long): List<Message?> {
|
||||
val result = mutableListOf<Message?>()
|
||||
for (message in messages) {
|
||||
if (message.id > till) {
|
||||
result.add(message)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NO_MESSAGES = 0L
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.github.gotify.log.Log;
|
||||
|
||||
public class NotificationSupport {
|
||||
public static final class Group {
|
||||
public static final String MESSAGES = "GOTIFY_GROUP_MESSAGES";
|
||||
}
|
||||
|
||||
public static final class Channel {
|
||||
public static final String FOREGROUND = "gotify_foreground";
|
||||
public static final String MESSAGES_IMPORTANCE_MIN = "gotify_messages_min_importance";
|
||||
public static final String MESSAGES_IMPORTANCE_LOW = "gotify_messages_low_importance";
|
||||
public static final String MESSAGES_IMPORTANCE_DEFAULT =
|
||||
"gotify_messages_default_importance";
|
||||
public static final String MESSAGES_IMPORTANCE_HIGH = "gotify_messages_high_importance";
|
||||
}
|
||||
|
||||
public static final class ID {
|
||||
public static final int FOREGROUND = -1;
|
||||
public static final int GROUPED = -2;
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
public static void createChannels(NotificationManager notificationManager) {
|
||||
try {
|
||||
// Low importance so that persistent notification can be sorted towards bottom of
|
||||
// notification shade. Also prevents vibrations caused by persistent notification
|
||||
NotificationChannel foreground =
|
||||
new NotificationChannel(
|
||||
Channel.FOREGROUND,
|
||||
"Gotify foreground notification",
|
||||
NotificationManager.IMPORTANCE_LOW);
|
||||
foreground.setShowBadge(false);
|
||||
|
||||
NotificationChannel messagesImportanceMin =
|
||||
new NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_MIN,
|
||||
"Min priority messages (<1)",
|
||||
NotificationManager.IMPORTANCE_MIN);
|
||||
|
||||
NotificationChannel messagesImportanceLow =
|
||||
new NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_LOW,
|
||||
"Low priority messages (1-3)",
|
||||
NotificationManager.IMPORTANCE_LOW);
|
||||
|
||||
NotificationChannel messagesImportanceDefault =
|
||||
new NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_DEFAULT,
|
||||
"Normal priority messages (4-7)",
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
messagesImportanceDefault.enableLights(true);
|
||||
messagesImportanceDefault.setLightColor(Color.CYAN);
|
||||
messagesImportanceDefault.enableVibration(true);
|
||||
|
||||
NotificationChannel messagesImportanceHigh =
|
||||
new NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_HIGH,
|
||||
"High priority messages (>7)",
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
messagesImportanceHigh.enableLights(true);
|
||||
messagesImportanceHigh.setLightColor(Color.CYAN);
|
||||
messagesImportanceHigh.enableVibration(true);
|
||||
|
||||
notificationManager.createNotificationChannel(foreground);
|
||||
notificationManager.createNotificationChannel(messagesImportanceMin);
|
||||
notificationManager.createNotificationChannel(messagesImportanceLow);
|
||||
notificationManager.createNotificationChannel(messagesImportanceDefault);
|
||||
notificationManager.createNotificationChannel(messagesImportanceHigh);
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not create channel", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map {@link com.github.gotify.client.model.Message#getPriority() Gotify message priorities to
|
||||
* Android channels.
|
||||
*
|
||||
* <pre>
|
||||
* Gotify Priority | Android Importance
|
||||
* <= 0 | min
|
||||
* 1-3 | low
|
||||
* 4-7 | default
|
||||
* >= 8 | high
|
||||
* </pre>
|
||||
*
|
||||
* @param priority the Gotify priority to convert to a notification channel as a long.
|
||||
* @return the identifier of the notification channel as a String.
|
||||
*/
|
||||
public static String convertPriorityToChannel(long priority) {
|
||||
if (priority < 1) {
|
||||
return Channel.MESSAGES_IMPORTANCE_MIN;
|
||||
} else if (priority < 4) {
|
||||
return Channel.MESSAGES_IMPORTANCE_LOW;
|
||||
} else if (priority < 8) {
|
||||
return Channel.MESSAGES_IMPORTANCE_DEFAULT;
|
||||
} else {
|
||||
return Channel.MESSAGES_IMPORTANCE_HIGH;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
app/src/main/java/com/github/gotify/NotificationSupport.kt
Normal file
106
app/src/main/java/com/github/gotify/NotificationSupport.kt
Normal file
@@ -0,0 +1,106 @@
|
||||
package com.github.gotify
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.gotify.log.Log
|
||||
|
||||
object NotificationSupport {
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun createChannels(notificationManager: NotificationManager) {
|
||||
try {
|
||||
// Low importance so that persistent notification can be sorted towards bottom of
|
||||
// notification shade. Also prevents vibrations caused by persistent notification
|
||||
val foreground = NotificationChannel(
|
||||
Channel.FOREGROUND,
|
||||
"Gotify foreground notification",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
)
|
||||
foreground.setShowBadge(false)
|
||||
|
||||
val messagesImportanceMin = NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_MIN,
|
||||
"Min priority messages (<1)",
|
||||
NotificationManager.IMPORTANCE_MIN
|
||||
)
|
||||
|
||||
val messagesImportanceLow = NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_LOW,
|
||||
"Low priority messages (1-3)",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
)
|
||||
|
||||
val messagesImportanceDefault = NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_DEFAULT,
|
||||
"Normal priority messages (4-7)",
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
messagesImportanceDefault.enableLights(true)
|
||||
messagesImportanceDefault.lightColor = Color.CYAN
|
||||
messagesImportanceDefault.enableVibration(true)
|
||||
|
||||
val messagesImportanceHigh = NotificationChannel(
|
||||
Channel.MESSAGES_IMPORTANCE_HIGH,
|
||||
"High priority messages (>7)",
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
messagesImportanceHigh.enableLights(true)
|
||||
messagesImportanceHigh.lightColor = Color.CYAN
|
||||
messagesImportanceHigh.enableVibration(true)
|
||||
|
||||
notificationManager.createNotificationChannel(foreground)
|
||||
notificationManager.createNotificationChannel(messagesImportanceMin)
|
||||
notificationManager.createNotificationChannel(messagesImportanceLow)
|
||||
notificationManager.createNotificationChannel(messagesImportanceDefault)
|
||||
notificationManager.createNotificationChannel(messagesImportanceHigh)
|
||||
} catch (e: Exception) {
|
||||
Log.e("Could not create channel", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map {@link com.github.gotify.client.model.Message#getPriority() Gotify message priorities to
|
||||
* Android channels.
|
||||
*
|
||||
* <pre>
|
||||
* Gotify Priority | Android Importance
|
||||
* <= 0 | min
|
||||
* 1-3 | low
|
||||
* 4-7 | default
|
||||
* >= 8 | high
|
||||
* </pre>
|
||||
*
|
||||
* @param priority the Gotify priority to convert to a notification channel as a long.
|
||||
* @return the identifier of the notification channel as a String.
|
||||
*/
|
||||
fun convertPriorityToChannel(priority: Long): String {
|
||||
return if (priority < 1) {
|
||||
Channel.MESSAGES_IMPORTANCE_MIN
|
||||
} else if (priority < 4) {
|
||||
Channel.MESSAGES_IMPORTANCE_LOW
|
||||
} else if (priority < 8) {
|
||||
Channel.MESSAGES_IMPORTANCE_DEFAULT
|
||||
} else {
|
||||
Channel.MESSAGES_IMPORTANCE_HIGH
|
||||
}
|
||||
}
|
||||
|
||||
object Group {
|
||||
const val MESSAGES = "GOTIFY_GROUP_MESSAGES"
|
||||
}
|
||||
|
||||
object Channel {
|
||||
const val FOREGROUND = "gotify_foreground"
|
||||
const val MESSAGES_IMPORTANCE_MIN = "gotify_messages_min_importance"
|
||||
const val MESSAGES_IMPORTANCE_LOW = "gotify_messages_low_importance"
|
||||
const val MESSAGES_IMPORTANCE_DEFAULT = "gotify_messages_default_importance"
|
||||
const val MESSAGES_IMPORTANCE_HIGH = "gotify_messages_high_importance"
|
||||
}
|
||||
|
||||
object ID {
|
||||
const val FOREGROUND = -1
|
||||
const val GROUPED = -2
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.github.gotify;
|
||||
|
||||
public class SSLSettings {
|
||||
public boolean validateSSL;
|
||||
public String cert;
|
||||
|
||||
public SSLSettings(boolean validateSSL, String cert) {
|
||||
this.validateSSL = validateSSL;
|
||||
this.cert = cert;
|
||||
}
|
||||
}
|
||||
3
app/src/main/java/com/github/gotify/SSLSettings.kt
Normal file
3
app/src/main/java/com/github/gotify/SSLSettings.kt
Normal file
@@ -0,0 +1,3 @@
|
||||
package com.github.gotify
|
||||
|
||||
class SSLSettings(val validateSSL: Boolean, val cert: String)
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import com.github.gotify.client.model.User;
|
||||
|
||||
public class Settings {
|
||||
private final SharedPreferences sharedPreferences;
|
||||
|
||||
public Settings(Context context) {
|
||||
sharedPreferences = context.getSharedPreferences("gotify", Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public void url(String url) {
|
||||
sharedPreferences.edit().putString("url", url).apply();
|
||||
}
|
||||
|
||||
public String url() {
|
||||
return sharedPreferences.getString("url", null);
|
||||
}
|
||||
|
||||
public boolean tokenExists() {
|
||||
return token() != null;
|
||||
}
|
||||
|
||||
public String token() {
|
||||
return sharedPreferences.getString("token", null);
|
||||
}
|
||||
|
||||
public void token(String token) {
|
||||
sharedPreferences.edit().putString("token", token).apply();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
url(null);
|
||||
token(null);
|
||||
validateSSL(true);
|
||||
cert(null);
|
||||
}
|
||||
|
||||
public void user(String name, boolean admin) {
|
||||
sharedPreferences.edit().putString("username", name).putBoolean("admin", admin).apply();
|
||||
}
|
||||
|
||||
public User user() {
|
||||
String username = sharedPreferences.getString("username", null);
|
||||
boolean admin = sharedPreferences.getBoolean("admin", false);
|
||||
if (username != null) {
|
||||
return new User().name(username).admin(admin);
|
||||
} else {
|
||||
return new User().name("UNKNOWN").admin(false);
|
||||
}
|
||||
}
|
||||
|
||||
public String serverVersion() {
|
||||
return sharedPreferences.getString("version", "UNKNOWN");
|
||||
}
|
||||
|
||||
public void serverVersion(String version) {
|
||||
sharedPreferences.edit().putString("version", version).apply();
|
||||
}
|
||||
|
||||
private boolean validateSSL() {
|
||||
return sharedPreferences.getBoolean("validateSSL", true);
|
||||
}
|
||||
|
||||
public void validateSSL(boolean validateSSL) {
|
||||
sharedPreferences.edit().putBoolean("validateSSL", validateSSL).apply();
|
||||
}
|
||||
|
||||
private String cert() {
|
||||
return sharedPreferences.getString("cert", null);
|
||||
}
|
||||
|
||||
public void cert(String cert) {
|
||||
sharedPreferences.edit().putString("cert", cert).apply();
|
||||
}
|
||||
|
||||
public SSLSettings sslSettings() {
|
||||
return new SSLSettings(validateSSL(), cert());
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/com/github/gotify/Settings.kt
Normal file
56
app/src/main/java/com/github/gotify/Settings.kt
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.github.gotify
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.github.gotify.client.model.User
|
||||
|
||||
class Settings(context: Context) {
|
||||
private val sharedPreferences: SharedPreferences
|
||||
var url: String
|
||||
get() = sharedPreferences.getString("url", "")!!
|
||||
set(value) = sharedPreferences.edit().putString("url", value).apply()
|
||||
var token: String
|
||||
get() = sharedPreferences.getString("token", "")!!
|
||||
set(value) = sharedPreferences.edit().putString("token", value).apply()
|
||||
var user: User? = null
|
||||
get() {
|
||||
val username = sharedPreferences.getString("username", null)
|
||||
val admin = sharedPreferences.getBoolean("admin", false)
|
||||
return if (username != null) {
|
||||
User().name(username).admin(admin)
|
||||
} else {
|
||||
User().name("UNKNOWN").admin(false)
|
||||
}
|
||||
}
|
||||
private set
|
||||
var serverVersion: String
|
||||
get() = sharedPreferences.getString("version", "UNKNOWN")!!
|
||||
set(value) = sharedPreferences.edit().putString("version", value).apply()
|
||||
var cert: String
|
||||
get() = sharedPreferences.getString("cert", "")!!
|
||||
set(value) = sharedPreferences.edit().putString("cert", value).apply()
|
||||
var validateSSL: Boolean
|
||||
get() = sharedPreferences.getBoolean("validateSSL", true)
|
||||
set(value) = sharedPreferences.edit().putBoolean("validateSSL", value).apply()
|
||||
|
||||
init {
|
||||
sharedPreferences = context.getSharedPreferences("gotify", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
fun tokenExists(): Boolean = token.isNotEmpty()
|
||||
|
||||
fun clear() {
|
||||
url = ""
|
||||
token = ""
|
||||
validateSSL = true
|
||||
cert = ""
|
||||
}
|
||||
|
||||
fun setUser(name: String?, admin: Boolean) {
|
||||
sharedPreferences.edit().putString("username", name).putBoolean("admin", admin).apply()
|
||||
}
|
||||
|
||||
fun sslSettings(): SSLSettings {
|
||||
return SSLSettings(validateSSL, cert)
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.github.gotify.client.JSON;
|
||||
import com.github.gotify.log.Log;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.gson.Gson;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.squareup.picasso.Target;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import okio.Buffer;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
|
||||
public class Utils {
|
||||
public static final Gson JSON = new JSON().getGson();
|
||||
|
||||
public static void showSnackBar(Activity activity, String message) {
|
||||
View rootView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
Snackbar.make(rootView, message, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
public static int longToInt(long value) {
|
||||
return (int) (value % Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static String dateToRelative(OffsetDateTime data) {
|
||||
long time = data.toInstant().toEpochMilli();
|
||||
long now = System.currentTimeMillis();
|
||||
return DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public static String resolveAbsoluteUrl(String baseURL, String target) {
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
URI targetUri = new URI(target);
|
||||
if (targetUri.isAbsolute()) {
|
||||
return target;
|
||||
}
|
||||
return new URL(new URL(baseURL), target).toString();
|
||||
} catch (MalformedURLException | URISyntaxException e) {
|
||||
Log.e("Could not resolve absolute url", e);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
public static Target toDrawable(Resources resources, DrawableReceiver drawableReceiver) {
|
||||
return new Target() {
|
||||
@Override
|
||||
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
|
||||
drawableReceiver.loaded(new BitmapDrawable(resources, bitmap));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
|
||||
Log.e("Bitmap failed", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareLoad(Drawable placeHolderDrawable) {}
|
||||
};
|
||||
}
|
||||
|
||||
public static String readFileFromStream(@NonNull InputStream inputStream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String currentLine;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
while ((currentLine = reader.readLine()) != null) {
|
||||
sb.append(currentLine).append("\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("failed to read input");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public interface DrawableReceiver {
|
||||
void loaded(Drawable drawable);
|
||||
}
|
||||
|
||||
public static InputStream stringToInputStream(String str) {
|
||||
if (str == null) return null;
|
||||
return new Buffer().writeUtf8(str).inputStream();
|
||||
}
|
||||
|
||||
public static <T> T first(T[] data) {
|
||||
if (data.length != 1) {
|
||||
throw new IllegalArgumentException("must be one element");
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
}
|
||||
101
app/src/main/java/com/github/gotify/Utils.kt
Normal file
101
app/src/main/java/com/github/gotify/Utils.kt
Normal file
@@ -0,0 +1,101 @@
|
||||
package com.github.gotify
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.format.DateUtils
|
||||
import android.view.View
|
||||
import com.github.gotify.client.JSON
|
||||
import com.github.gotify.log.Log
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.gson.Gson
|
||||
import com.squareup.picasso.Picasso.LoadedFrom
|
||||
import com.squareup.picasso.Target
|
||||
import okio.Buffer
|
||||
import org.threeten.bp.OffsetDateTime
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
import java.net.URL
|
||||
|
||||
object Utils {
|
||||
val JSON: Gson = JSON().gson
|
||||
|
||||
fun showSnackBar(activity: Activity, message: String?) {
|
||||
val rootView = activity.window.decorView.findViewById<View>(R.id.content)
|
||||
Snackbar.make(rootView, message!!, Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
fun longToInt(value: Long): Int {
|
||||
return (value % Int.MAX_VALUE).toInt()
|
||||
}
|
||||
|
||||
fun dateToRelative(data: OffsetDateTime): String {
|
||||
val time = data.toInstant().toEpochMilli()
|
||||
val now = System.currentTimeMillis()
|
||||
return DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS)
|
||||
.toString()
|
||||
}
|
||||
|
||||
fun resolveAbsoluteUrl(baseURL: String?, target: String?): String? {
|
||||
return if (target == null) {
|
||||
null
|
||||
} else try {
|
||||
val targetUri = URI(target)
|
||||
if (targetUri.isAbsolute) {
|
||||
target
|
||||
} else URL(URL(baseURL), target).toString()
|
||||
} catch (e: MalformedURLException) {
|
||||
Log.e("Could not resolve absolute url", e)
|
||||
target
|
||||
} catch (e: URISyntaxException) {
|
||||
Log.e("Could not resolve absolute url", e)
|
||||
target
|
||||
}
|
||||
}
|
||||
|
||||
fun toDrawable(resources: Resources?, drawableReceiver: DrawableReceiver): Target {
|
||||
return object : Target {
|
||||
override fun onBitmapLoaded(bitmap: Bitmap, from: LoadedFrom) {
|
||||
drawableReceiver.loaded(BitmapDrawable(resources, bitmap))
|
||||
}
|
||||
|
||||
override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {
|
||||
Log.e("Bitmap failed", e)
|
||||
}
|
||||
|
||||
override fun onPrepareLoad(placeHolderDrawable: Drawable) {}
|
||||
}
|
||||
}
|
||||
|
||||
fun readFileFromStream(inputStream: InputStream): String {
|
||||
val sb = StringBuilder()
|
||||
var currentLine: String?
|
||||
try {
|
||||
BufferedReader(InputStreamReader(inputStream)).use { reader ->
|
||||
while (reader.readLine().also {
|
||||
currentLine = it
|
||||
} != null) {
|
||||
sb.append(currentLine).append("\n")
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
throw IllegalArgumentException("failed to read input")
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun stringToInputStream(str: String?): InputStream? {
|
||||
return if (str == null) null else Buffer().writeUtf8(str).inputStream()
|
||||
}
|
||||
|
||||
fun interface DrawableReceiver {
|
||||
fun loaded(drawable: Drawable?)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user