diff --git a/pom.xml b/pom.xml
index ad964784..493e857e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -197,7 +197,7 @@
true
-
+
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
@@ -207,6 +207,7 @@
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+ -parameters
true
diff --git a/src/main/java/it/auties/whatsapp/api/ErrorHandler.java b/src/main/java/it/auties/whatsapp/api/ErrorHandler.java
index 58e1ce38..ab3650f0 100644
--- a/src/main/java/it/auties/whatsapp/api/ErrorHandler.java
+++ b/src/main/java/it/auties/whatsapp/api/ErrorHandler.java
@@ -118,7 +118,11 @@ enum Location {
/**
* Called when an error occurs when serializing or deserializing a Whatsapp message
*/
- MESSAGE
+ MESSAGE,
+ /**
+ * Called when syncing messages after first QR scan
+ */
+ HISTORY_SYNC
}
/**
diff --git a/src/main/java/it/auties/whatsapp/api/WebHistoryLength.java b/src/main/java/it/auties/whatsapp/api/WebHistoryLength.java
index e5651448..ffdc8ef0 100644
--- a/src/main/java/it/auties/whatsapp/api/WebHistoryLength.java
+++ b/src/main/java/it/auties/whatsapp/api/WebHistoryLength.java
@@ -1,26 +1,46 @@
package it.auties.whatsapp.api;
+import it.auties.whatsapp.util.Spec;
+
/**
* The constants of this enumerated type describe the various chat history's codeLength that Whatsapp
* can send on the first login attempt
*/
-public enum WebHistoryLength {
+public record WebHistoryLength(int size) {
+ private static final WebHistoryLength ZERO = new WebHistoryLength(0);
+ private static final WebHistoryLength STANDARD = new WebHistoryLength(Spec.Whatsapp.DEFAULT_HISTORY_SIZE);
+ private static final WebHistoryLength EXTENDED = new WebHistoryLength(Integer.MAX_VALUE);
+
/**
* Discards history
* This will save a lot of system resources, but you won't have access to messages sent before the session creation
*/
- ZERO,
+ public static WebHistoryLength zero() {
+ return ZERO;
+ }
+
/**
* This is the default setting for the web client
* This is also the recommended setting
*/
- STANDARD,
+ public static WebHistoryLength standard() {
+ return STANDARD;
+ }
/**
* This will contain most of your messages
* Unless you 100% know what you are doing don't use this
* It consumes a lot of system resources
*/
- EXTENDED,
+ public static WebHistoryLength extended() {
+ return EXTENDED;
+ }
+
+ /**
+ * Custom size
+ */
+ public static WebHistoryLength custom(int size) {
+ return new WebHistoryLength(size);
+ }
}
diff --git a/src/main/java/it/auties/whatsapp/api/Whatsapp.java b/src/main/java/it/auties/whatsapp/api/Whatsapp.java
index 898cf5b3..6c66199c 100644
--- a/src/main/java/it/auties/whatsapp/api/Whatsapp.java
+++ b/src/main/java/it/auties/whatsapp/api/Whatsapp.java
@@ -23,10 +23,14 @@
import it.auties.whatsapp.model.call.CallStatus;
import it.auties.whatsapp.model.chat.*;
import it.auties.whatsapp.model.companion.CompanionLinkResult;
-import it.auties.whatsapp.model.contact.*;
+import it.auties.whatsapp.model.contact.Contact;
+import it.auties.whatsapp.model.contact.ContactStatus;
import it.auties.whatsapp.model.info.ContextInfo;
import it.auties.whatsapp.model.info.MessageInfo;
import it.auties.whatsapp.model.info.MessageInfoBuilder;
+import it.auties.whatsapp.model.jid.Jid;
+import it.auties.whatsapp.model.jid.JidProvider;
+import it.auties.whatsapp.model.jid.JidServer;
import it.auties.whatsapp.model.media.AttachmentType;
import it.auties.whatsapp.model.media.MediaFile;
import it.auties.whatsapp.model.media.MutableAttachmentProvider;
@@ -48,11 +52,10 @@
import it.auties.whatsapp.model.privacy.PrivacySettingEntry;
import it.auties.whatsapp.model.privacy.PrivacySettingType;
import it.auties.whatsapp.model.privacy.PrivacySettingValue;
-import it.auties.whatsapp.model.request.*;
+import it.auties.whatsapp.model.request.ContactStatusQuery;
+import it.auties.whatsapp.model.request.MessageSendRequest;
import it.auties.whatsapp.model.response.ContactStatusResponse;
-import it.auties.whatsapp.model.response.ChannelResponse;
import it.auties.whatsapp.model.response.HasWhatsappResponse;
-import it.auties.whatsapp.model.response.RecommendedChannelsResponse;
import it.auties.whatsapp.model.setting.LocaleSettings;
import it.auties.whatsapp.model.setting.PushNameSettings;
import it.auties.whatsapp.model.signal.auth.*;
@@ -64,7 +67,6 @@
import it.auties.whatsapp.socket.SocketState;
import it.auties.whatsapp.util.*;
import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
import org.jilt.Builder;
import org.jilt.BuilderStyle;
import org.jilt.Opt;
@@ -79,7 +81,10 @@
import java.time.ZonedDateTime;
import java.time.chrono.ChronoZonedDateTime;
import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -298,7 +303,7 @@ public CompletableFuture logout() {
* @return the same instance wrapped in a completable future
*/
@SafeVarargs
- public final CompletableFuture changePrivacySetting(@NonNull PrivacySettingType type, @NonNull PrivacySettingValue value, @NonNull T @NonNull ... excluded) {
+ public final CompletableFuture changePrivacySetting(@NonNull PrivacySettingType type, @NonNull PrivacySettingValue value, @NonNull T @NonNull ... excluded) {
Validate.isTrue(type.isSupported(value),
"Cannot change setting %s to %s: this toggle cannot be used because Whatsapp doesn't support it", value.name(), type.name());
var attributes = Attributes.of()
@@ -306,7 +311,7 @@ public final CompletableFuture changePr
.put("value", value.data())
.put("dhash", "none", () -> value == PrivacySettingValue.CONTACTS_EXCEPT)
.toMap();
- var excludedJids = Arrays.stream(excluded).map(ContactJidProvider::toJid).toList();
+ var excludedJids = Arrays.stream(excluded).map(JidProvider::toJid).toList();
var children = value != PrivacySettingValue.CONTACTS_EXCEPT ? null : excludedJids.stream()
.map(entry -> Node.of("user", Map.of("jid", entry, "action", "add")))
.toList();
@@ -315,7 +320,7 @@ public final CompletableFuture changePr
.thenApply(ignored -> this);
}
- private void onPrivacyFeatureChanged(PrivacySettingType type, PrivacySettingValue value, List excludedJids) {
+ private void onPrivacyFeatureChanged(PrivacySettingType type, PrivacySettingValue value, List excludedJids) {
var newEntry = new PrivacySettingEntry(type, value, excludedJids);
var oldEntry = store().findPrivacySetting(type);
store().addPrivacySetting(type, newEntry);
@@ -391,7 +396,7 @@ public CompletableFuture changeStatus(@NonNull String newStatus) {
* @param jid the contact whose status the api should receive updates on
* @return a CompletableFuture
*/
- public CompletableFuture subscribeToPresence(@NonNull T jid) {
+ public CompletableFuture subscribeToPresence(@NonNull T jid) {
return socketHandler.subscribeToPresence(jid).thenApplyAsync(ignored -> jid);
}
@@ -449,7 +454,7 @@ public CompletableFuture sendReaction(@NonNull MessageMetadataProvi
* @param message the message to send
* @return a CompletableFuture
*/
- public CompletableFuture sendMessage(@NonNull ContactJidProvider chat, @NonNull String message) {
+ public CompletableFuture sendMessage(@NonNull JidProvider chat, @NonNull String message) {
return sendMessage(chat, MessageContainer.of(message));
}
@@ -460,7 +465,7 @@ public CompletableFuture sendMessage(@NonNull ContactJidProvider ch
* @param message the message to send
* @return a CompletableFuture
*/
- public CompletableFuture sendMessage(@NonNull ContactJidProvider chat, @NonNull Message message) {
+ public CompletableFuture sendMessage(@NonNull JidProvider chat, @NonNull Message message) {
return sendMessage(chat, MessageContainer.of(message));
}
@@ -471,7 +476,7 @@ public CompletableFuture sendMessage(@NonNull ContactJidProvider ch
* @param message the message to send
* @return a CompletableFuture
*/
- public CompletableFuture sendMessage(@NonNull ContactJidProvider chat, @NonNull MessageContainer message) {
+ public CompletableFuture sendMessage(@NonNull JidProvider chat, @NonNull MessageContainer message) {
var key = new MessageKeyBuilder()
.id(MessageKey.randomId())
.chatJid(chat.toJid())
@@ -484,7 +489,7 @@ public CompletableFuture sendMessage(@NonNull ContactJidProvider ch
.key(key)
.message(message)
.timestampSeconds(Clock.nowSeconds())
- .broadcast(chat.toJid().hasServer(ContactJidServer.BROADCAST))
+ .broadcast(chat.toJid().hasServer(JidServer.BROADCAST))
.build();
return sendMessage(info);
}
@@ -524,7 +529,7 @@ private CompletableFuture attributeMessageMetadata(MessageInfo info) {
* @param chat the target chat
* @return a CompletableFuture
*/
- public CompletableFuture markRead(@NonNull T chat) {
+ public CompletableFuture markRead(@NonNull T chat) {
return mark(chat, true).thenComposeAsync(ignored -> markAllAsRead(chat)).thenApplyAsync(ignored -> chat);
}
@@ -700,7 +705,7 @@ private CompletableFuture attributeGroupInviteMessage(MessageInfo info, Gr
return CompletableFuture.completedFuture(null);
}
- private CompletableFuture mark(@NonNull T chat, boolean read) {
+ private CompletableFuture mark(@NonNull T chat, boolean read) {
if(store().clientType() == ClientType.MOBILE){
// TODO: Send notification to companions
store().findChatByJid(chat.toJid())
@@ -716,7 +721,7 @@ private CompletableFuture mark(@NonNull T chat
return socketHandler.pushPatch(request).thenApplyAsync(ignored -> chat);
}
- private CompletableFuture markAllAsRead(ContactJidProvider chat) {
+ private CompletableFuture markAllAsRead(JidProvider chat) {
var all = store()
.findChatByJid(chat.toJid())
.stream()
@@ -731,7 +736,7 @@ private LinkPreviewMedia compareDimensions(LinkPreviewMedia first, LinkPreviewMe
return first.width() * first.height() > second.width() * second.height() ? first : second;
}
- private ActionMessageRangeSync createRange(ContactJidProvider chat, boolean allMessages) {
+ private ActionMessageRangeSync createRange(JidProvider chat, boolean allMessages) {
var known = store().findChatByJid(chat.toJid()).orElseGet(() -> store().addNewChat(chat.toJid()));
return new ActionMessageRangeSync(known, allMessages);
}
@@ -789,8 +794,8 @@ public CompletableFuture awaitReply(@NonNull String id) {
* @param contact the contact to check
* @return a CompletableFuture that wraps a non-null response
*/
- public CompletableFuture hasWhatsapp(@NonNull ContactJidProvider contact) {
- return hasWhatsapp(new ContactJidProvider[]{contact}).thenApply(result -> result.get(contact.toJid()));
+ public CompletableFuture hasWhatsapp(@NonNull JidProvider contact) {
+ return hasWhatsapp(new JidProvider[]{contact}).thenApply(result -> result.get(contact.toJid()));
}
/**
@@ -799,7 +804,7 @@ public CompletableFuture hasWhatsapp(@NonNull ContactJidPro
* @param contacts the contacts to check
* @return a CompletableFuture that wraps a non-null map
*/
- public CompletableFuture