Fix IDs (#1016)
* Allow any String IDs as long as they're sortable * Allow any String IDs as long as they're sortable
This commit is contained in:
parent
87364edd98
commit
22ee1dc5df
12 changed files with 148 additions and 73 deletions
|
@ -16,8 +16,6 @@
|
|||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.Job;
|
||||
|
@ -28,15 +26,18 @@ import com.keylesspalace.tusky.entity.Notification;
|
|||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import retrofit2.Response;
|
||||
|
||||
import static com.keylesspalace.tusky.util.StringUtils.isLessThan;
|
||||
|
||||
/**
|
||||
* Created by charlag on 31/10/17.
|
||||
*/
|
||||
|
@ -111,28 +112,24 @@ public final class NotificationPullJobCreator implements JobCreator {
|
|||
|
||||
private void onNotificationsReceived(AccountEntity account, List<Notification> notificationList) {
|
||||
Collections.reverse(notificationList);
|
||||
BigInteger newId = new BigInteger(account.getLastNotificationId());
|
||||
BigInteger newestId = BigInteger.ZERO;
|
||||
String newId = account.getLastNotificationId();
|
||||
String newestId = "";
|
||||
boolean isFirstOfBatch = true;
|
||||
|
||||
for (Notification notification : notificationList) {
|
||||
BigInteger currentId = new BigInteger(notification.getId());
|
||||
if (isBiggerThan(currentId, newestId)) {
|
||||
String currentId = notification.getId();
|
||||
if (isLessThan(newestId, currentId)) {
|
||||
newestId = currentId;
|
||||
}
|
||||
|
||||
if (isBiggerThan(currentId, newId)) {
|
||||
if (isLessThan(newId, currentId)) {
|
||||
NotificationHelper.make(context, notification, account, isFirstOfBatch);
|
||||
isFirstOfBatch = false;
|
||||
}
|
||||
}
|
||||
|
||||
account.setLastNotificationId(newestId.toString());
|
||||
account.setLastNotificationId(newestId);
|
||||
accountManager.saveAccount(account);
|
||||
}
|
||||
|
||||
private boolean isBiggerThan(BigInteger newId, BigInteger lastShownNotificationId) {
|
||||
return lastShownNotificationId.compareTo(newId) < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
public static String randomAlphanumericString(int count) {
|
||||
char[] chars = new char[count];
|
||||
Random random = new Random();
|
||||
final String POSSIBLE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
for (int i = 0; i < count; i++) {
|
||||
chars[i] = POSSIBLE_CHARS.charAt(random.nextInt(POSSIBLE_CHARS.length()));
|
||||
}
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
@file:JvmName("StringUtils")
|
||||
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import java.util.Random
|
||||
|
||||
|
||||
private const val POSSIBLE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
fun randomAlphanumericString(count: Int): String {
|
||||
val chars = CharArray(count)
|
||||
val random = Random()
|
||||
for (i in 0 until count) {
|
||||
chars[i] = POSSIBLE_CHARS[random.nextInt(POSSIBLE_CHARS.length)]
|
||||
}
|
||||
return String(chars)
|
||||
}
|
||||
|
||||
// We sort statuses by ID. Something we need to invent some ID for placeholder.
|
||||
// Not sure if inc()/dec() should be made `operator` or not
|
||||
|
||||
/**
|
||||
* "Increment" string so that during sorting it's bigger than [this].
|
||||
*/
|
||||
fun String.inc(): String {
|
||||
// We assume that we will stay in the safe range for now
|
||||
val builder = this.toCharArray()
|
||||
builder.last().inc()
|
||||
return String(builder)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* "Decrement" string so that during sorting it's smaller than [this].
|
||||
*/
|
||||
fun String.dec(): String {
|
||||
val builder = this.toCharArray()
|
||||
var i = builder.lastIndex
|
||||
while (i > 0) {
|
||||
if (builder[i] > '0') {
|
||||
builder[i] = builder[i].dec()
|
||||
break
|
||||
} else {
|
||||
builder[i] = 'z'
|
||||
}
|
||||
i--
|
||||
}
|
||||
// All characters were '0'
|
||||
if (i == 0 && this.isNotEmpty()) {
|
||||
// Remove one character
|
||||
return String(builder.copyOfRange(1, builder.size))
|
||||
}
|
||||
|
||||
return String(builder)
|
||||
}
|
||||
|
||||
/**
|
||||
* A < B (strictly) by length and then by content.
|
||||
* Examples:
|
||||
* "abc" < "bcd"
|
||||
* "ab" < "abc"
|
||||
* "cb" < "abc"
|
||||
* not: "ab" < "ab"
|
||||
* not: "abc" > "cb"
|
||||
*/
|
||||
fun String.isLessThan(other: String): Boolean {
|
||||
return when {
|
||||
this.length < other.length -> true
|
||||
this.length > other.length -> false
|
||||
else -> this < other
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue