Track the first time a megaphone appeared.

master
Greyson Parrelli 2020-01-30 11:33:34 -05:00
parent 22f9bfeceb
commit 9f7b2e2cfd
10 changed files with 67 additions and 26 deletions

View File

@ -475,6 +475,8 @@ public class ConversationListFragment extends MainFragment implements LoaderMana
megaphone.getOnVisibleListener().onVisible(megaphone, this);
}
}
viewModel.onMegaphoneVisible(megaphone);
}
private void updateReminders() {

View File

@ -14,7 +14,6 @@ import android.text.TextUtils;
import org.thoughtcrime.securesms.conversationlist.model.SearchResult;
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.megaphone.Megaphone;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
import org.thoughtcrime.securesms.megaphone.Megaphones;
@ -75,6 +74,10 @@ class ConversationListViewModel extends ViewModel {
megaphone.postValue(null);
}
void onMegaphoneVisible(@NonNull Megaphone visible) {
megaphoneRepository.markVisible(visible.getEvent());
}
void updateQuery(String query) {
lastQuery = query;
debouncer.publish(() -> searchRepository.query(query, result -> {

View File

@ -23,17 +23,19 @@ public class MegaphoneDatabase extends Database {
private static final String TABLE_NAME = "megaphone";
private static final String ID = "_id";
private static final String EVENT = "event";
private static final String SEEN_COUNT = "seen_count";
private static final String LAST_SEEN = "last_seen";
private static final String FINISHED = "finished";
private static final String ID = "_id";
private static final String EVENT = "event";
private static final String SEEN_COUNT = "seen_count";
private static final String LAST_SEEN = "last_seen";
private static final String FIRST_VISIBLE = "first_visible";
private static final String FINISHED = "finished";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
EVENT + " TEXT UNIQUE, " +
SEEN_COUNT + " INTEGER, " +
LAST_SEEN + " INTEGER, " +
FINISHED + " INTEGER)";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
EVENT + " TEXT UNIQUE, " +
SEEN_COUNT + " INTEGER, " +
LAST_SEEN + " INTEGER, " +
FIRST_VISIBLE + " INTEGER, " +
FINISHED + " INTEGER)";
MegaphoneDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
super(context, databaseHelper);
@ -62,18 +64,29 @@ public class MegaphoneDatabase extends Database {
try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
String event = cursor.getString(cursor.getColumnIndexOrThrow(EVENT));
int seenCount = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_COUNT));
long lastSeen = cursor.getLong(cursor.getColumnIndexOrThrow(LAST_SEEN));
boolean finished = cursor.getInt(cursor.getColumnIndexOrThrow(FINISHED)) == 1;
String event = cursor.getString(cursor.getColumnIndexOrThrow(EVENT));
int seenCount = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_COUNT));
long lastSeen = cursor.getLong(cursor.getColumnIndexOrThrow(LAST_SEEN));
long firstVisible = cursor.getLong(cursor.getColumnIndexOrThrow(FIRST_VISIBLE));
boolean finished = cursor.getInt(cursor.getColumnIndexOrThrow(FINISHED)) == 1;
records.add(new MegaphoneRecord(Event.fromKey(event), seenCount, lastSeen, finished));
records.add(new MegaphoneRecord(Event.fromKey(event), seenCount, lastSeen, firstVisible, finished));
}
}
return records;
}
public void markFirstVisible(@NonNull Event event, long time) {
String query = EVENT + " = ?";
String[] args = new String[]{event.getKey()};
ContentValues values = new ContentValues();
values.put(FIRST_VISIBLE, time);
databaseHelper.getWritableDatabase().update(TABLE_NAME, values, query, args);
}
public void markSeen(@NonNull Event event, int seenCount, long lastSeen) {
String query = EVENT + " = ?";
String[] args = new String[]{event.getKey()};

View File

@ -104,8 +104,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int SPLIT_PROFILE_NAMES = 43;
private static final int STICKER_PACK_ORDER = 44;
private static final int MEGAPHONES = 45;
private static final int MEGAPHONE_FIRST_APPEARANCE = 46;
private static final int DATABASE_VERSION = 45;
private static final int DATABASE_VERSION = 46;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@ -719,6 +720,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
"finished INTEGER)");
}
if (oldVersion < MEGAPHONE_FIRST_APPEARANCE) {
db.execSQL("ALTER TABLE megaphone ADD COLUMN first_visible INTEGER DEFAULT 0");
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();

View File

@ -9,13 +9,15 @@ public class MegaphoneRecord {
private final Megaphones.Event event;
private final int seenCount;
private final long lastSeen;
private final long firstVisible;
private final boolean finished;
public MegaphoneRecord(@NonNull Megaphones.Event event, int seenCount, long lastSeen, boolean finished) {
this.event = event;
this.seenCount = seenCount;
this.lastSeen = lastSeen;
this.finished = finished;
public MegaphoneRecord(@NonNull Megaphones.Event event, int seenCount, long lastSeen, long firstVisible, boolean finished) {
this.event = event;
this.seenCount = seenCount;
this.lastSeen = lastSeen;
this.firstVisible = firstVisible;
this.finished = finished;
}
public @NonNull Megaphones.Event getEvent() {
@ -30,6 +32,10 @@ public class MegaphoneRecord {
return lastSeen;
}
public long getFirstVisible() {
return firstVisible;
}
public boolean isFinished() {
return finished;
}

View File

@ -9,7 +9,7 @@ final class ForeverSchedule implements MegaphoneSchedule {
}
@Override
public boolean shouldDisplay(int seenCount, long lastSeen, long currentTime) {
public boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime) {
return enabled;
}
}

View File

@ -69,6 +69,18 @@ public class MegaphoneRepository {
});
}
@MainThread
public void markVisible(@NonNull Megaphones.Event event) {
long time = System.currentTimeMillis();
executor.execute(() -> {
if (getRecord(event).getFirstVisible() == 0) {
database.markFirstVisible(event, time);
resetDatabaseCache();
}
});
}
@MainThread
public void markSeen(@NonNull Megaphone megaphone) {
long lastSeen = System.currentTimeMillis();

View File

@ -1,5 +1,5 @@
package org.thoughtcrime.securesms.megaphone;
public interface MegaphoneSchedule {
boolean shouldDisplay(int seenCount, long lastSeen, long currentTime);
boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime);
}

View File

@ -45,7 +45,7 @@ public final class Megaphones {
MegaphoneRecord record = Objects.requireNonNull(records.get(e.getKey()));
MegaphoneSchedule schedule = e.getValue();
return !record.isFinished() && schedule.shouldDisplay(record.getSeenCount(), record.getLastSeen(), currentTime);
return !record.isFinished() && schedule.shouldDisplay(record.getSeenCount(), record.getLastSeen(), record.getFirstVisible(), currentTime);
})
.map(Map.Entry::getKey)
.map(records::get)

View File

@ -9,7 +9,7 @@ class RecurringSchedule implements MegaphoneSchedule {
}
@Override
public boolean shouldDisplay(int seenCount, long lastSeen, long currentTime) {
public boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime) {
if (seenCount == 0) {
return true;
}