feat(base,interface,android): Move more logic to Moxxy

This commit is contained in:
PapaTutuWawa 2023-08-30 20:34:38 +02:00
parent 27440067cd
commit be58288025
10 changed files with 794 additions and 122 deletions

View File

@ -105,6 +105,18 @@ public class Api {
} }
} }
public enum NotificationChannelImportance {
MIN(0),
HIGH(1),
DEFAULT(2);
final int index;
private NotificationChannelImportance(final int index) {
this.index = index;
}
}
/** Generated class from Pigeon that represents data sent in messages. */ /** Generated class from Pigeon that represents data sent in messages. */
public static final class NotificationMessageContent { public static final class NotificationMessageContent {
/** The textual body of the message. */ /** The textual body of the message. */
@ -194,6 +206,17 @@ public class Api {
/** Generated class from Pigeon that represents data sent in messages. */ /** Generated class from Pigeon that represents data sent in messages. */
public static final class NotificationMessage { public static final class NotificationMessage {
/** The grouping key for the notification. */
private @Nullable String groupId;
public @Nullable String getGroupId() {
return groupId;
}
public void setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
}
/** The sender of the message. */ /** The sender of the message. */
private @Nullable String sender; private @Nullable String sender;
@ -260,6 +283,13 @@ public class Api {
public static final class Builder { public static final class Builder {
private @Nullable String groupId;
public @NonNull Builder setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
return this;
}
private @Nullable String sender; private @Nullable String sender;
public @NonNull Builder setSender(@Nullable String setterArg) { public @NonNull Builder setSender(@Nullable String setterArg) {
@ -297,6 +327,7 @@ public class Api {
public @NonNull NotificationMessage build() { public @NonNull NotificationMessage build() {
NotificationMessage pigeonReturn = new NotificationMessage(); NotificationMessage pigeonReturn = new NotificationMessage();
pigeonReturn.setGroupId(groupId);
pigeonReturn.setSender(sender); pigeonReturn.setSender(sender);
pigeonReturn.setJid(jid); pigeonReturn.setJid(jid);
pigeonReturn.setContent(content); pigeonReturn.setContent(content);
@ -308,7 +339,8 @@ public class Api {
@NonNull @NonNull
ArrayList<Object> toList() { ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(5); ArrayList<Object> toListResult = new ArrayList<Object>(6);
toListResult.add(groupId);
toListResult.add(sender); toListResult.add(sender);
toListResult.add(jid); toListResult.add(jid);
toListResult.add((content == null) ? null : content.toList()); toListResult.add((content == null) ? null : content.toList());
@ -319,15 +351,17 @@ public class Api {
static @NonNull NotificationMessage fromList(@NonNull ArrayList<Object> list) { static @NonNull NotificationMessage fromList(@NonNull ArrayList<Object> list) {
NotificationMessage pigeonResult = new NotificationMessage(); NotificationMessage pigeonResult = new NotificationMessage();
Object sender = list.get(0); Object groupId = list.get(0);
pigeonResult.setGroupId((String) groupId);
Object sender = list.get(1);
pigeonResult.setSender((String) sender); pigeonResult.setSender((String) sender);
Object jid = list.get(1); Object jid = list.get(2);
pigeonResult.setJid((String) jid); pigeonResult.setJid((String) jid);
Object content = list.get(2); Object content = list.get(3);
pigeonResult.setContent((content == null) ? null : NotificationMessageContent.fromList((ArrayList<Object>) content)); pigeonResult.setContent((content == null) ? null : NotificationMessageContent.fromList((ArrayList<Object>) content));
Object timestamp = list.get(3); Object timestamp = list.get(4);
pigeonResult.setTimestamp((timestamp == null) ? null : ((timestamp instanceof Integer) ? (Integer) timestamp : (Long) timestamp)); pigeonResult.setTimestamp((timestamp == null) ? null : ((timestamp instanceof Integer) ? (Integer) timestamp : (Long) timestamp));
Object avatarPath = list.get(4); Object avatarPath = list.get(5);
pigeonResult.setAvatarPath((String) avatarPath); pigeonResult.setAvatarPath((String) avatarPath);
return pigeonResult; return pigeonResult;
} }
@ -419,6 +453,17 @@ public class Api {
this.isGroupchat = setterArg; this.isGroupchat = setterArg;
} }
/** The id for notification grouping. */
private @Nullable String groupId;
public @Nullable String getGroupId() {
return groupId;
}
public void setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
}
/** Additional data to include. */ /** Additional data to include. */
private @Nullable Map<String, String> extra; private @Nullable Map<String, String> extra;
@ -477,6 +522,13 @@ public class Api {
return this; return this;
} }
private @Nullable String groupId;
public @NonNull Builder setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
return this;
}
private @Nullable Map<String, String> extra; private @Nullable Map<String, String> extra;
public @NonNull Builder setExtra(@Nullable Map<String, String> setterArg) { public @NonNull Builder setExtra(@Nullable Map<String, String> setterArg) {
@ -492,6 +544,7 @@ public class Api {
pigeonReturn.setJid(jid); pigeonReturn.setJid(jid);
pigeonReturn.setMessages(messages); pigeonReturn.setMessages(messages);
pigeonReturn.setIsGroupchat(isGroupchat); pigeonReturn.setIsGroupchat(isGroupchat);
pigeonReturn.setGroupId(groupId);
pigeonReturn.setExtra(extra); pigeonReturn.setExtra(extra);
return pigeonReturn; return pigeonReturn;
} }
@ -499,13 +552,14 @@ public class Api {
@NonNull @NonNull
ArrayList<Object> toList() { ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(7); ArrayList<Object> toListResult = new ArrayList<Object>(8);
toListResult.add(title); toListResult.add(title);
toListResult.add(id); toListResult.add(id);
toListResult.add(channelId); toListResult.add(channelId);
toListResult.add(jid); toListResult.add(jid);
toListResult.add(messages); toListResult.add(messages);
toListResult.add(isGroupchat); toListResult.add(isGroupchat);
toListResult.add(groupId);
toListResult.add(extra); toListResult.add(extra);
return toListResult; return toListResult;
} }
@ -524,7 +578,9 @@ public class Api {
pigeonResult.setMessages((List<NotificationMessage>) messages); pigeonResult.setMessages((List<NotificationMessage>) messages);
Object isGroupchat = list.get(5); Object isGroupchat = list.get(5);
pigeonResult.setIsGroupchat((Boolean) isGroupchat); pigeonResult.setIsGroupchat((Boolean) isGroupchat);
Object extra = list.get(6); Object groupId = list.get(6);
pigeonResult.setGroupId((String) groupId);
Object extra = list.get(7);
pigeonResult.setExtra((Map<String, String>) extra); pigeonResult.setExtra((Map<String, String>) extra);
return pigeonResult; return pigeonResult;
} }
@ -574,6 +630,17 @@ public class Api {
this.channelId = setterArg; this.channelId = setterArg;
} }
/** The id for notification grouping. */
private @Nullable String groupId;
public @Nullable String getGroupId() {
return groupId;
}
public void setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
}
/** The id of the notification. */ /** The id of the notification. */
private @NonNull Long id; private @NonNull Long id;
@ -628,6 +695,13 @@ public class Api {
return this; return this;
} }
private @Nullable String groupId;
public @NonNull Builder setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
return this;
}
private @Nullable Long id; private @Nullable Long id;
public @NonNull Builder setId(@NonNull Long setterArg) { public @NonNull Builder setId(@NonNull Long setterArg) {
@ -647,6 +721,7 @@ public class Api {
pigeonReturn.setTitle(title); pigeonReturn.setTitle(title);
pigeonReturn.setBody(body); pigeonReturn.setBody(body);
pigeonReturn.setChannelId(channelId); pigeonReturn.setChannelId(channelId);
pigeonReturn.setGroupId(groupId);
pigeonReturn.setId(id); pigeonReturn.setId(id);
pigeonReturn.setIcon(icon); pigeonReturn.setIcon(icon);
return pigeonReturn; return pigeonReturn;
@ -655,10 +730,11 @@ public class Api {
@NonNull @NonNull
ArrayList<Object> toList() { ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(5); ArrayList<Object> toListResult = new ArrayList<Object>(6);
toListResult.add(title); toListResult.add(title);
toListResult.add(body); toListResult.add(body);
toListResult.add(channelId); toListResult.add(channelId);
toListResult.add(groupId);
toListResult.add(id); toListResult.add(id);
toListResult.add(icon == null ? null : icon.index); toListResult.add(icon == null ? null : icon.index);
return toListResult; return toListResult;
@ -672,9 +748,11 @@ public class Api {
pigeonResult.setBody((String) body); pigeonResult.setBody((String) body);
Object channelId = list.get(2); Object channelId = list.get(2);
pigeonResult.setChannelId((String) channelId); pigeonResult.setChannelId((String) channelId);
Object id = list.get(3); Object groupId = list.get(3);
pigeonResult.setGroupId((String) groupId);
Object id = list.get(4);
pigeonResult.setId((id == null) ? null : ((id instanceof Integer) ? (Integer) id : (Long) id)); pigeonResult.setId((id == null) ? null : ((id instanceof Integer) ? (Integer) id : (Long) id));
Object icon = list.get(4); Object icon = list.get(5);
pigeonResult.setIcon(icon == null ? null : NotificationIcon.values()[(int) icon]); pigeonResult.setIcon(icon == null ? null : NotificationIcon.values()[(int) icon]);
return pigeonResult; return pigeonResult;
} }
@ -1001,6 +1079,293 @@ public class Api {
} }
} }
/** Generated class from Pigeon that represents data sent in messages. */
public static final class NotificationGroup {
private @NonNull String id;
public @NonNull String getId() {
return id;
}
public void setId(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"id\" is null.");
}
this.id = setterArg;
}
private @NonNull String description;
public @NonNull String getDescription() {
return description;
}
public void setDescription(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"description\" is null.");
}
this.description = setterArg;
}
/** Constructor is non-public to enforce null safety; use Builder. */
NotificationGroup() {}
public static final class Builder {
private @Nullable String id;
public @NonNull Builder setId(@NonNull String setterArg) {
this.id = setterArg;
return this;
}
private @Nullable String description;
public @NonNull Builder setDescription(@NonNull String setterArg) {
this.description = setterArg;
return this;
}
public @NonNull NotificationGroup build() {
NotificationGroup pigeonReturn = new NotificationGroup();
pigeonReturn.setId(id);
pigeonReturn.setDescription(description);
return pigeonReturn;
}
}
@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(2);
toListResult.add(id);
toListResult.add(description);
return toListResult;
}
static @NonNull NotificationGroup fromList(@NonNull ArrayList<Object> list) {
NotificationGroup pigeonResult = new NotificationGroup();
Object id = list.get(0);
pigeonResult.setId((String) id);
Object description = list.get(1);
pigeonResult.setDescription((String) description);
return pigeonResult;
}
}
/** Generated class from Pigeon that represents data sent in messages. */
public static final class NotificationChannel {
private @NonNull String title;
public @NonNull String getTitle() {
return title;
}
public void setTitle(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"title\" is null.");
}
this.title = setterArg;
}
private @NonNull String description;
public @NonNull String getDescription() {
return description;
}
public void setDescription(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"description\" is null.");
}
this.description = setterArg;
}
private @NonNull String id;
public @NonNull String getId() {
return id;
}
public void setId(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"id\" is null.");
}
this.id = setterArg;
}
private @NonNull NotificationChannelImportance importance;
public @NonNull NotificationChannelImportance getImportance() {
return importance;
}
public void setImportance(@NonNull NotificationChannelImportance setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"importance\" is null.");
}
this.importance = setterArg;
}
private @NonNull Boolean showBadge;
public @NonNull Boolean getShowBadge() {
return showBadge;
}
public void setShowBadge(@NonNull Boolean setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"showBadge\" is null.");
}
this.showBadge = setterArg;
}
private @Nullable String groupId;
public @Nullable String getGroupId() {
return groupId;
}
public void setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
}
private @NonNull Boolean vibration;
public @NonNull Boolean getVibration() {
return vibration;
}
public void setVibration(@NonNull Boolean setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"vibration\" is null.");
}
this.vibration = setterArg;
}
private @NonNull Boolean enableLights;
public @NonNull Boolean getEnableLights() {
return enableLights;
}
public void setEnableLights(@NonNull Boolean setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"enableLights\" is null.");
}
this.enableLights = setterArg;
}
/** Constructor is non-public to enforce null safety; use Builder. */
NotificationChannel() {}
public static final class Builder {
private @Nullable String title;
public @NonNull Builder setTitle(@NonNull String setterArg) {
this.title = setterArg;
return this;
}
private @Nullable String description;
public @NonNull Builder setDescription(@NonNull String setterArg) {
this.description = setterArg;
return this;
}
private @Nullable String id;
public @NonNull Builder setId(@NonNull String setterArg) {
this.id = setterArg;
return this;
}
private @Nullable NotificationChannelImportance importance;
public @NonNull Builder setImportance(@NonNull NotificationChannelImportance setterArg) {
this.importance = setterArg;
return this;
}
private @Nullable Boolean showBadge;
public @NonNull Builder setShowBadge(@NonNull Boolean setterArg) {
this.showBadge = setterArg;
return this;
}
private @Nullable String groupId;
public @NonNull Builder setGroupId(@Nullable String setterArg) {
this.groupId = setterArg;
return this;
}
private @Nullable Boolean vibration;
public @NonNull Builder setVibration(@NonNull Boolean setterArg) {
this.vibration = setterArg;
return this;
}
private @Nullable Boolean enableLights;
public @NonNull Builder setEnableLights(@NonNull Boolean setterArg) {
this.enableLights = setterArg;
return this;
}
public @NonNull NotificationChannel build() {
NotificationChannel pigeonReturn = new NotificationChannel();
pigeonReturn.setTitle(title);
pigeonReturn.setDescription(description);
pigeonReturn.setId(id);
pigeonReturn.setImportance(importance);
pigeonReturn.setShowBadge(showBadge);
pigeonReturn.setGroupId(groupId);
pigeonReturn.setVibration(vibration);
pigeonReturn.setEnableLights(enableLights);
return pigeonReturn;
}
}
@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(8);
toListResult.add(title);
toListResult.add(description);
toListResult.add(id);
toListResult.add(importance == null ? null : importance.index);
toListResult.add(showBadge);
toListResult.add(groupId);
toListResult.add(vibration);
toListResult.add(enableLights);
return toListResult;
}
static @NonNull NotificationChannel fromList(@NonNull ArrayList<Object> list) {
NotificationChannel pigeonResult = new NotificationChannel();
Object title = list.get(0);
pigeonResult.setTitle((String) title);
Object description = list.get(1);
pigeonResult.setDescription((String) description);
Object id = list.get(2);
pigeonResult.setId((String) id);
Object importance = list.get(3);
pigeonResult.setImportance(importance == null ? null : NotificationChannelImportance.values()[(int) importance]);
Object showBadge = list.get(4);
pigeonResult.setShowBadge((Boolean) showBadge);
Object groupId = list.get(5);
pigeonResult.setGroupId((String) groupId);
Object vibration = list.get(6);
pigeonResult.setVibration((Boolean) vibration);
Object enableLights = list.get(7);
pigeonResult.setEnableLights((Boolean) enableLights);
return pigeonResult;
}
}
public interface Result<T> { public interface Result<T> {
@SuppressWarnings("UnknownNullness") @SuppressWarnings("UnknownNullness")
void success(T result); void success(T result);
@ -1021,14 +1386,18 @@ public class Api {
case (byte) 129: case (byte) 129:
return MessagingNotification.fromList((ArrayList<Object>) readValue(buffer)); return MessagingNotification.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 130: case (byte) 130:
return NotificationEvent.fromList((ArrayList<Object>) readValue(buffer)); return NotificationChannel.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 131: case (byte) 131:
return NotificationI18nData.fromList((ArrayList<Object>) readValue(buffer)); return NotificationEvent.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 132: case (byte) 132:
return NotificationMessage.fromList((ArrayList<Object>) readValue(buffer)); return NotificationGroup.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 133: case (byte) 133:
return NotificationMessageContent.fromList((ArrayList<Object>) readValue(buffer)); return NotificationI18nData.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 134: case (byte) 134:
return NotificationMessage.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 135:
return NotificationMessageContent.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 136:
return RegularNotification.fromList((ArrayList<Object>) readValue(buffer)); return RegularNotification.fromList((ArrayList<Object>) readValue(buffer));
default: default:
return super.readValueOfType(type, buffer); return super.readValueOfType(type, buffer);
@ -1043,20 +1412,26 @@ public class Api {
} else if (value instanceof MessagingNotification) { } else if (value instanceof MessagingNotification) {
stream.write(129); stream.write(129);
writeValue(stream, ((MessagingNotification) value).toList()); writeValue(stream, ((MessagingNotification) value).toList());
} else if (value instanceof NotificationEvent) { } else if (value instanceof NotificationChannel) {
stream.write(130); stream.write(130);
writeValue(stream, ((NotificationEvent) value).toList()); writeValue(stream, ((NotificationChannel) value).toList());
} else if (value instanceof NotificationI18nData) { } else if (value instanceof NotificationEvent) {
stream.write(131); stream.write(131);
writeValue(stream, ((NotificationEvent) value).toList());
} else if (value instanceof NotificationGroup) {
stream.write(132);
writeValue(stream, ((NotificationGroup) value).toList());
} else if (value instanceof NotificationI18nData) {
stream.write(133);
writeValue(stream, ((NotificationI18nData) value).toList()); writeValue(stream, ((NotificationI18nData) value).toList());
} else if (value instanceof NotificationMessage) { } else if (value instanceof NotificationMessage) {
stream.write(132); stream.write(134);
writeValue(stream, ((NotificationMessage) value).toList()); writeValue(stream, ((NotificationMessage) value).toList());
} else if (value instanceof NotificationMessageContent) { } else if (value instanceof NotificationMessageContent) {
stream.write(133); stream.write(135);
writeValue(stream, ((NotificationMessageContent) value).toList()); writeValue(stream, ((NotificationMessageContent) value).toList());
} else if (value instanceof RegularNotification) { } else if (value instanceof RegularNotification) {
stream.write(134); stream.write(136);
writeValue(stream, ((RegularNotification) value).toList()); writeValue(stream, ((RegularNotification) value).toList());
} else { } else {
super.writeValue(stream, value); super.writeValue(stream, value);
@ -1067,7 +1442,13 @@ public class Api {
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
public interface MoxplatformApi { public interface MoxplatformApi {
/** Notification APIs */ /** Notification APIs */
void createNotificationChannel(@NonNull String title, @NonNull String description, @NonNull String id, @NonNull Boolean urgent); void createNotificationGroups(@NonNull List<NotificationGroup> groups);
void deleteNotificationGroups(@NonNull List<String> ids);
void createNotificationChannels(@NonNull List<NotificationChannel> channels);
void deleteNotificationChannels(@NonNull List<String> ids);
void showMessagingNotification(@NonNull MessagingNotification notification); void showMessagingNotification(@NonNull MessagingNotification notification);
@ -1112,18 +1493,87 @@ public class Api {
{ {
BasicMessageChannel<Object> channel = BasicMessageChannel<Object> channel =
new BasicMessageChannel<>( new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannel", getCodec()); binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationGroups", getCodec());
if (api != null) { if (api != null) {
channel.setMessageHandler( channel.setMessageHandler(
(message, reply) -> { (message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>(); ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message; ArrayList<Object> args = (ArrayList<Object>) message;
String titleArg = (String) args.get(0); List<NotificationGroup> groupsArg = (List<NotificationGroup>) args.get(0);
String descriptionArg = (String) args.get(1);
String idArg = (String) args.get(2);
Boolean urgentArg = (Boolean) args.get(3);
try { try {
api.createNotificationChannel(titleArg, descriptionArg, idArg, urgentArg); api.createNotificationGroups(groupsArg);
wrapped.add(0, null);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.deleteNotificationGroups", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
List<String> idsArg = (List<String>) args.get(0);
try {
api.deleteNotificationGroups(idsArg);
wrapped.add(0, null);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannels", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
List<NotificationChannel> channelsArg = (List<NotificationChannel>) args.get(0);
try {
api.createNotificationChannels(channelsArg);
wrapped.add(0, null);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.deleteNotificationChannels", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
List<String> idsArg = (List<String>) args.get(0);
try {
api.deleteNotificationChannels(idsArg);
wrapped.add(0, null); wrapped.add(0, null);
} }
catch (Throwable exception) { catch (Throwable exception) {

View File

@ -100,46 +100,6 @@ public class BackgroundService extends Service implements MethodChannel.MethodCa
.apply(); .apply();
} }
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = getSystemService(NotificationManager.class);
// Create a special notification group for the foreground service notification to prevent
// message notifications from getting grouped with it in >= Android 13.
notificationManager.createNotificationChannelGroup(
new NotificationChannelGroup(
GROUP_KEY_FOREGROUND,
"The foreground notification"
)
);
notificationManager.createNotificationChannelGroup(
new NotificationChannelGroup(
GROUP_KEY_MESSAGES,
"Messages"
)
);
notificationManager.createNotificationChannelGroup(
new NotificationChannelGroup(
GROUP_KEY_OTHER,
"Other"
)
);
NotificationChannel channel = new NotificationChannel(
"FOREGROUND_DEFAULT",
"Moxxy Background Service",
NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("Executing Moxxy in the background");
// Prevent showing a badge in the Launcher
channel.setShowBadge(false);
channel.setGroup("foreground");
// Create the channel
notificationManager.createNotificationChannel(channel);
}
}
protected void updateNotificationInfo() { protected void updateNotificationInfo() {
String packageName = getApplicationContext().getPackageName(); String packageName = getApplicationContext().getPackageName();
Intent i = getPackageManager().getLaunchIntentForPackage(packageName); Intent i = getPackageManager().getLaunchIntentForPackage(packageName);
@ -269,7 +229,6 @@ public class BackgroundService extends Service implements MethodChannel.MethodCa
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
createNotificationChannel();
notificationBody = "Preparing..."; notificationBody = "Preparing...";
updateNotificationInfo(); updateNotificationInfo();
} }

View File

@ -6,6 +6,8 @@ import static androidx.core.content.ContextCompat.startActivity;
import static me.polynom.moxplatform_android.ConstantsKt.MOXPLATFORM_FILEPROVIDER_ID; import static me.polynom.moxplatform_android.ConstantsKt.MOXPLATFORM_FILEPROVIDER_ID;
import static me.polynom.moxplatform_android.ConstantsKt.SHARED_PREFERENCES_KEY; import static me.polynom.moxplatform_android.ConstantsKt.SHARED_PREFERENCES_KEY;
import static me.polynom.moxplatform_android.CryptoKt.*; import static me.polynom.moxplatform_android.CryptoKt.*;
import static me.polynom.moxplatform_android.NotificationsKt.createNotificationChannelsImpl;
import static me.polynom.moxplatform_android.NotificationsKt.createNotificationGroupsImpl;
import static me.polynom.moxplatform_android.RecordSentMessageKt.*; import static me.polynom.moxplatform_android.RecordSentMessageKt.*;
import static me.polynom.moxplatform_android.ThumbnailsKt.generateVideoThumbnailImplementation; import static me.polynom.moxplatform_android.ThumbnailsKt.generateVideoThumbnailImplementation;
@ -225,13 +227,29 @@ public class MoxplatformAndroidPlugin extends BroadcastReceiver implements Flutt
} }
@Override @Override
public void createNotificationChannel(@NonNull String title, @NonNull String description, @NonNull String id, @NonNull Boolean urgent) { public void createNotificationGroups(@NonNull List<NotificationGroup> groups) {
final NotificationChannel channel = new NotificationChannel(id, title, urgent ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT); createNotificationGroupsImpl(context, groups);
channel.enableVibration(true); }
channel.enableLights(true);
channel.setDescription(description); @Override
final NotificationManager manager = getSystemService(context, NotificationManager.class); public void deleteNotificationGroups(@NonNull List<String> ids) {
manager.createNotificationChannel(channel); final NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
for (final String id : ids) {
notificationManager.deleteNotificationChannelGroup(id);
}
}
@Override
public void createNotificationChannels(@NonNull List<Api.NotificationChannel> channels) {
createNotificationChannelsImpl(context, channels);
}
@Override
public void deleteNotificationChannels(@NonNull List<String> ids) {
final NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
for (final String id : ids) {
notificationManager.deleteNotificationChannel(id);
}
} }
@Override @Override

View File

@ -161,7 +161,6 @@ class NotificationReceiver : BroadcastReceiver() {
val recoveredBuilder = Notification.Builder.recoverBuilder(context, notification).apply { val recoveredBuilder = Notification.Builder.recoverBuilder(context, notification).apply {
style = newStyle style = newStyle
setOnlyAlertOnce(true) setOnlyAlertOnce(true)
setGroup(GROUP_KEY_MESSAGES)
} }
NotificationManagerCompat.from(context).notify(id, recoveredBuilder.build()) NotificationManagerCompat.from(context).notify(id, recoveredBuilder.build())
} }

View File

@ -1,11 +1,15 @@
package me.polynom.moxplatform_android package me.polynom.moxplatform_android
import android.app.Notification import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Color import android.graphics.Color
import android.os.Build
import android.util.Log import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@ -14,7 +18,6 @@ import androidx.core.app.RemoteInput
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.IconCompat
import java.io.File import java.io.File
import java.lang.Exception
/* /*
* Holds "persistent" data for notifications, like i18n strings. While not useful now, this is * Holds "persistent" data for notifications, like i18n strings. While not useful now, this is
@ -87,6 +90,37 @@ object NotificationDataManager {
} }
} }
fun createNotificationGroupsImpl(context: Context, groups: List<Api.NotificationGroup>) {
val notificationManager = context.getSystemService(NotificationManager::class.java)
for (group in groups) {
notificationManager.createNotificationChannelGroup(
NotificationChannelGroup(group.id, group.description),
)
}
}
fun createNotificationChannelsImpl(context: Context, channels: List<Api.NotificationChannel>) {
val notificationManager = context.getSystemService(NotificationManager::class.java)
for (channel in channels) {
val importance = when(channel.importance) {
Api.NotificationChannelImportance.DEFAULT -> NotificationManager.IMPORTANCE_DEFAULT
Api.NotificationChannelImportance.MIN -> NotificationManager.IMPORTANCE_MIN
Api.NotificationChannelImportance.HIGH -> NotificationManager.IMPORTANCE_HIGH
}
val notificationChannel = NotificationChannel(channel.id, channel.title, importance).apply {
description = channel.description
enableVibration(channel.vibration)
enableLights(channel.enableLights)
setShowBadge(channel.showBadge)
if (channel.groupId != null) {
group = channel.groupId
}
}
notificationManager.createNotificationChannel(notificationChannel)
}
}
/// Show a messaging style notification described by @notification. /// Show a messaging style notification described by @notification.
fun showMessagingNotification(context: Context, notification: Api.MessagingNotification) { fun showMessagingNotification(context: Context, notification: Api.MessagingNotification) {
// Build the actions // Build the actions
@ -255,7 +289,9 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
} }
// Prevent grouping with the foreground service // Prevent grouping with the foreground service
setGroup(GROUP_KEY_MESSAGES) if (notification.groupId != null) {
setGroup(notification.groupId)
}
setAllowSystemGeneratedContextualActions(true) setAllowSystemGeneratedContextualActions(true)
setCategory(Notification.CATEGORY_MESSAGE) setCategory(Notification.CATEGORY_MESSAGE)
@ -282,7 +318,9 @@ fun showNotification(context: Context, notification: Api.RegularNotification) {
Api.NotificationIcon.NONE -> {} Api.NotificationIcon.NONE -> {}
} }
setGroup(GROUP_KEY_OTHER) if (notification.groupId != null) {
setGroup(notification.groupId)
}
}.build() }.build()
// Post the notification // Post the notification

View File

@ -9,13 +9,24 @@ class AndroidNotificationsImplementation extends NotificationsImplementation {
const EventChannel('me.polynom/notification_stream'); const EventChannel('me.polynom/notification_stream');
@override @override
Future<void> createNotificationChannel( Future<void> createNotificationChannels(
String title, List<NotificationChannel> channels) async {
String description, return _api.createNotificationChannels(channels);
String id, }
bool urgent,
) async { @override
return _api.createNotificationChannel(title, description, id, urgent); Future<void> deleteNotificationChannels(List<String> ids) {
return _api.deleteNotificationChannels(ids);
}
@override
Future<void> createNotificationGroups(List<NotificationGroup> groups) async {
return _api.createNotificationGroups(groups);
}
@override
Future<void> deleteNotificationGroups(List<String> ids) {
return _api.deleteNotificationGroups(ids);
} }
@override @override

View File

@ -32,6 +32,12 @@ enum FallbackIconType {
notes, notes,
} }
enum NotificationChannelImportance {
MIN,
HIGH,
DEFAULT,
}
class NotificationMessageContent { class NotificationMessageContent {
NotificationMessageContent({ NotificationMessageContent({
this.body, this.body,
@ -67,6 +73,7 @@ class NotificationMessageContent {
class NotificationMessage { class NotificationMessage {
NotificationMessage({ NotificationMessage({
this.groupId,
this.sender, this.sender,
this.jid, this.jid,
required this.content, required this.content,
@ -74,6 +81,9 @@ class NotificationMessage {
this.avatarPath, this.avatarPath,
}); });
/// The grouping key for the notification.
String? groupId;
/// The sender of the message. /// The sender of the message.
String? sender; String? sender;
@ -91,6 +101,7 @@ class NotificationMessage {
Object encode() { Object encode() {
return <Object?>[ return <Object?>[
groupId,
sender, sender,
jid, jid,
content.encode(), content.encode(),
@ -102,11 +113,12 @@ class NotificationMessage {
static NotificationMessage decode(Object result) { static NotificationMessage decode(Object result) {
result as List<Object?>; result as List<Object?>;
return NotificationMessage( return NotificationMessage(
sender: result[0] as String?, groupId: result[0] as String?,
jid: result[1] as String?, sender: result[1] as String?,
content: NotificationMessageContent.decode(result[2]! as List<Object?>), jid: result[2] as String?,
timestamp: result[3]! as int, content: NotificationMessageContent.decode(result[3]! as List<Object?>),
avatarPath: result[4] as String?, timestamp: result[4]! as int,
avatarPath: result[5] as String?,
); );
} }
} }
@ -119,6 +131,7 @@ class MessagingNotification {
required this.jid, required this.jid,
required this.messages, required this.messages,
required this.isGroupchat, required this.isGroupchat,
this.groupId,
this.extra, this.extra,
}); });
@ -140,6 +153,9 @@ class MessagingNotification {
/// Flag indicating whether this notification is from a groupchat or not. /// Flag indicating whether this notification is from a groupchat or not.
bool isGroupchat; bool isGroupchat;
/// The id for notification grouping.
String? groupId;
/// Additional data to include. /// Additional data to include.
Map<String?, String?>? extra; Map<String?, String?>? extra;
@ -151,6 +167,7 @@ class MessagingNotification {
jid, jid,
messages, messages,
isGroupchat, isGroupchat,
groupId,
extra, extra,
]; ];
} }
@ -164,7 +181,8 @@ class MessagingNotification {
jid: result[3]! as String, jid: result[3]! as String,
messages: (result[4] as List<Object?>?)!.cast<NotificationMessage?>(), messages: (result[4] as List<Object?>?)!.cast<NotificationMessage?>(),
isGroupchat: result[5]! as bool, isGroupchat: result[5]! as bool,
extra: (result[6] as Map<Object?, Object?>?)?.cast<String?, String?>(), groupId: result[6] as String?,
extra: (result[7] as Map<Object?, Object?>?)?.cast<String?, String?>(),
); );
} }
} }
@ -174,6 +192,7 @@ class RegularNotification {
required this.title, required this.title,
required this.body, required this.body,
required this.channelId, required this.channelId,
this.groupId,
required this.id, required this.id,
required this.icon, required this.icon,
}); });
@ -187,6 +206,9 @@ class RegularNotification {
/// The id of the channel to show the notification on. /// The id of the channel to show the notification on.
String channelId; String channelId;
/// The id for notification grouping.
String? groupId;
/// The id of the notification. /// The id of the notification.
int id; int id;
@ -198,6 +220,7 @@ class RegularNotification {
title, title,
body, body,
channelId, channelId,
groupId,
id, id,
icon.index, icon.index,
]; ];
@ -209,8 +232,9 @@ class RegularNotification {
title: result[0]! as String, title: result[0]! as String,
body: result[1]! as String, body: result[1]! as String,
channelId: result[2]! as String, channelId: result[2]! as String,
id: result[3]! as int, groupId: result[3] as String?,
icon: NotificationIcon.values[result[4]! as int], id: result[4]! as int,
icon: NotificationIcon.values[result[5]! as int],
); );
} }
} }
@ -323,6 +347,88 @@ class CryptographyResult {
} }
} }
class NotificationGroup {
NotificationGroup({
required this.id,
required this.description,
});
String id;
String description;
Object encode() {
return <Object?>[
id,
description,
];
}
static NotificationGroup decode(Object result) {
result as List<Object?>;
return NotificationGroup(
id: result[0]! as String,
description: result[1]! as String,
);
}
}
class NotificationChannel {
NotificationChannel({
required this.title,
required this.description,
required this.id,
required this.importance,
required this.showBadge,
this.groupId,
required this.vibration,
required this.enableLights,
});
String title;
String description;
String id;
NotificationChannelImportance importance;
bool showBadge;
String? groupId;
bool vibration;
bool enableLights;
Object encode() {
return <Object?>[
title,
description,
id,
importance.index,
showBadge,
groupId,
vibration,
enableLights,
];
}
static NotificationChannel decode(Object result) {
result as List<Object?>;
return NotificationChannel(
title: result[0]! as String,
description: result[1]! as String,
id: result[2]! as String,
importance: NotificationChannelImportance.values[result[3]! as int],
showBadge: result[4]! as bool,
groupId: result[5] as String?,
vibration: result[6]! as bool,
enableLights: result[7]! as bool,
);
}
}
class _MoxplatformApiCodec extends StandardMessageCodec { class _MoxplatformApiCodec extends StandardMessageCodec {
const _MoxplatformApiCodec(); const _MoxplatformApiCodec();
@override @override
@ -333,21 +439,27 @@ class _MoxplatformApiCodec extends StandardMessageCodec {
} else if (value is MessagingNotification) { } else if (value is MessagingNotification) {
buffer.putUint8(129); buffer.putUint8(129);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is NotificationEvent) { } else if (value is NotificationChannel) {
buffer.putUint8(130); buffer.putUint8(130);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is NotificationI18nData) { } else if (value is NotificationEvent) {
buffer.putUint8(131); buffer.putUint8(131);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is NotificationMessage) { } else if (value is NotificationGroup) {
buffer.putUint8(132); buffer.putUint8(132);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is NotificationMessageContent) { } else if (value is NotificationI18nData) {
buffer.putUint8(133); buffer.putUint8(133);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is RegularNotification) { } else if (value is NotificationMessage) {
buffer.putUint8(134); buffer.putUint8(134);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is NotificationMessageContent) {
buffer.putUint8(135);
writeValue(buffer, value.encode());
} else if (value is RegularNotification) {
buffer.putUint8(136);
writeValue(buffer, value.encode());
} else { } else {
super.writeValue(buffer, value); super.writeValue(buffer, value);
} }
@ -361,14 +473,18 @@ class _MoxplatformApiCodec extends StandardMessageCodec {
case 129: case 129:
return MessagingNotification.decode(readValue(buffer)!); return MessagingNotification.decode(readValue(buffer)!);
case 130: case 130:
return NotificationEvent.decode(readValue(buffer)!); return NotificationChannel.decode(readValue(buffer)!);
case 131: case 131:
return NotificationI18nData.decode(readValue(buffer)!); return NotificationEvent.decode(readValue(buffer)!);
case 132: case 132:
return NotificationMessage.decode(readValue(buffer)!); return NotificationGroup.decode(readValue(buffer)!);
case 133: case 133:
return NotificationMessageContent.decode(readValue(buffer)!); return NotificationI18nData.decode(readValue(buffer)!);
case 134: case 134:
return NotificationMessage.decode(readValue(buffer)!);
case 135:
return NotificationMessageContent.decode(readValue(buffer)!);
case 136:
return RegularNotification.decode(readValue(buffer)!); return RegularNotification.decode(readValue(buffer)!);
default: default:
return super.readValueOfType(type, buffer); return super.readValueOfType(type, buffer);
@ -387,15 +503,84 @@ class MoxplatformApi {
static const MessageCodec<Object?> codec = _MoxplatformApiCodec(); static const MessageCodec<Object?> codec = _MoxplatformApiCodec();
/// Notification APIs /// Notification APIs
Future<void> createNotificationChannel(String arg_title, Future<void> createNotificationGroups(
String arg_description, String arg_id, bool arg_urgent) async { List<NotificationGroup?> arg_groups) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>( final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannel', 'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationGroups',
codec, codec,
binaryMessenger: _binaryMessenger); binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel final List<Object?>? replyList =
.send(<Object?>[arg_title, arg_description, arg_id, arg_urgent]) await channel.send(<Object?>[arg_groups]) as List<Object?>?;
as List<Object?>?; if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> deleteNotificationGroups(List<String?> arg_ids) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.deleteNotificationGroups',
codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_ids]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> createNotificationChannels(
List<NotificationChannel?> arg_channels) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannels',
codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_channels]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return;
}
}
Future<void> deleteNotificationChannels(List<String?> arg_ids) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.deleteNotificationChannels',
codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_ids]) as List<Object?>?;
if (replyList == null) { if (replyList == null) {
throw PlatformException( throw PlatformException(
code: 'channel-error', code: 'channel-error',

View File

@ -4,12 +4,14 @@ import 'package:moxplatform_platform_interface/src/api.g.dart';
abstract class NotificationsImplementation { abstract class NotificationsImplementation {
/// Creates a notification channel with the name [title] and id [id]. If [urgent] is true, then /// Creates a notification channel with the name [title] and id [id]. If [urgent] is true, then
/// it configures the channel as carrying urgent information. /// it configures the channel as carrying urgent information.
Future<void> createNotificationChannel( Future<void> createNotificationChannels(List<NotificationChannel> channels);
String title,
String description, Future<void> deleteNotificationChannels(List<String> ids);
String id,
bool urgent, /// Creates notification groups.
); Future<void> createNotificationGroups(List<NotificationGroup> groups);
Future<void> deleteNotificationGroups(List<String> ids);
/// Shows a notification [notification] in the messaging style with everyting it needs. /// Shows a notification [notification] in the messaging style with everyting it needs.
Future<void> showMessagingNotification(MessagingNotification notification); Future<void> showMessagingNotification(MessagingNotification notification);

View File

@ -4,11 +4,22 @@ import 'package:moxplatform_platform_interface/src/notifications.dart';
class StubNotificationsImplementation extends NotificationsImplementation { class StubNotificationsImplementation extends NotificationsImplementation {
@override @override
Future<void> createNotificationChannel( Future<void> createNotificationChannels(
String title, List<NotificationChannel> channels,
String description, ) async {}
String id,
bool urgent, @override
Future<void> deleteNotificationChannels(
List<String> ids,
) async {}
Future<void> createNotificationGroups(
List<NotificationGroup> groups,
) async {}
@override
Future<void> deleteNotificationGroups(
List<String> ids,
) async {} ) async {}
@override @override