mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-08 05:42:06 +00:00
New app theming (#913)
* feat: start new app theming feature * feat: add some theming colours * refactor: start refactoring themes and colours to use dynamic attributes * feat: adding more colours and switching over default colours to be theme based instead of hard-coded or day/night specific * refactor: take a look at ocean light and logo colour * feat: global search colours for light and dark ocean * feat: more styling * feat: adding themes to conversation activity and refactoring the base theme to apply over the top of the activity's theme so it retains noActionBar etc * feat: add dynamic accent color * docs: add todo for changing how accent colour is applied * feat: update new theming to use override primary style so that the regular colorAccent attribute can be used in existing layouts * feat: coordinating styles across layouts, fixing up pinned icons and naming for conversation list items * refactor: re-styling layouts to match new themes and attributes. Need to figure out action mode close button * refactor: remove @color/text and replace with ?android:textColorPrimary to override in themes * refactor: add context theme wrapper to bottom sheet dialog that references accent color * fix: input bar bug fix and preference activity themes * refactor: new settings menu options * fix: crash for PNModeActivity.kt refactor: move ordering in seed dialog to match designs, copy changes to match new settings menu * feat: add new appearance settings activity * refactor: title and VM changes * fix: correct override * feat: add theme appearance screen UI features and start VM implementation. re-add legacy theme utils to get default for migration * fix: compile errors and missing themes from emoji features * refactor: remove background shape alteration and old bottom sheet styles, re-add the theme mode attr * feat: appearance screen wired up, just need to refresh theme * feat: add theme state recreation and fix match system settings option * refactor: add bottom margin * feat: explore custom preference category * feat: add the customized session theme for CorrectedPreferenceFragment * feat: replace AppProtectionPreferenceFragment to extend ListSummaryPreferenceFragment * refactor: change drawable style and remove explicit dividers * refactor: remove divider in CorrectedPreferenceFragment * feat: add theme state check on resume, might be jarring currently * feat: add preference divider elements for settings menu * refactor: settings menu redesigns * refactor: change led preference to integer and refactor TextSecurePreferences.kt * feat: add scroll parcel to save/restore hierarchy on restart with appearance changes * feat: add the conversations blocked contacts and refactor preference order and copy * feat: add blocked contacts activity, basic layout and vm * feat: add unblock DB functions and storage protocol, start working on the DB query state flow, might have to just implement recipient on modified listener * feat: add blocked contacts and notif recipient listeners * feat: add recipient db reader * feat: add blocked contact interactions and fix a theming crash for notifications * feat: introduce better equals and hashcode implementations to recipient, replace home diff util content check with hashcode-based comparison * feat: add settings menu vectors * fix: preview compile error * refactor: migrating settings menu to new designs * feat: help menu * refactor: simplify link opening * refactor: remove space * feat: refactor preferences and start theming for light mode options * refactor: fixing dark and light modes with dialogs * refactor: popup dialogs use proper themes now * refactor: alert dialogs and media edit fragments use attribute references * refactor: use input bar button attribute instead color control normal in vector tint * refactor: transparency, dialog fixes, notification fix * refactor: attrs and styles for buttons * fix: use prominent button color on the outline button's border * fix: fix the trash * refactor: remove the appearance * refactor: avatar placeholder generation, chips and element border styles * refactor: use colors instead of style references * refactor: theming changes to match designs and feedback * refactor: the titles are bold and the categories are tertiary coloured now * fix: appearance settings match preferences, search bottom bar uses themed attributes * refactor: increase setting button height * Update clear all data dialog * Update seed dialog * refactor: more qa feedback changes * feat: add new TLs and fa-rIR TLs * Update notification content dialog * Fix message requests clear all button text color * feat: re-add screenshot observer * refactor: make send tint accent color * feat: add unread background differences * fix: change unread count indicator * build: upgrade build numbers * Fix message requests popupmenu background color * fix: crash from attr reference in color attribute * build: upgrade build number * fix: message bubbles, thumbnail backgrounds, search bar visibility with input bar, attachment buttons * fix: tertiary text for keyboard page search view * fix: emoji overflow colour differences * fix: reaction pill dialog background is now correct colour * Add style to reactions tab layout * fix: appearance activity reverting primary color at correct time * fix: show call privacy warning every time instead of just once * fix: gradient background(?) and audio autoplay disable * fix: crash in all media containing documents * fix: reaction dialog heading fixes * Add style to reactions tab layout * fix: remove gradient backgrounds * fix: adding new reaction normal text attribute to try correct the tab layout * fix: ocean dark unread/read colours * build; update build number * build: update build number Co-authored-by: charles <charles@oxen.io>
This commit is contained in:
@@ -72,6 +72,11 @@ public abstract class Database {
|
||||
context.getContentResolver().notifyChange(DatabaseContentProviders.StickerPack.CONTENT_URI, null);
|
||||
}
|
||||
|
||||
protected void notifyRecipientListeners() {
|
||||
context.getContentResolver().notifyChange(DatabaseContentProviders.Recipient.CONTENT_URI, null);
|
||||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
protected void setNotifyConverationListeners(Cursor cursor, long threadId) {
|
||||
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getUriForThread(threadId));
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ public class DatabaseContentProviders {
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://network.loki.securesms.database.stickerpack");
|
||||
}
|
||||
|
||||
public static class Recipient extends NoopContentProvider {
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://network.loki.securesms.database.recipient");
|
||||
}
|
||||
|
||||
private static abstract class NoopContentProvider extends ContentProvider {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RecipientDatabase extends Database {
|
||||
@@ -232,6 +233,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(COLOR, color.serialize());
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setColor(color);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setDefaultSubscriptionId(@NonNull Recipient recipient, int defaultSubscriptionId) {
|
||||
@@ -239,6 +241,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(DEFAULT_SUBSCRIPTION_ID, defaultSubscriptionId);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setDefaultSubscriptionId(Optional.of(defaultSubscriptionId));
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setForceSmsSelection(@NonNull Recipient recipient, boolean forceSmsSelection) {
|
||||
@@ -246,6 +249,7 @@ public class RecipientDatabase extends Database {
|
||||
contentValues.put(FORCE_SMS_SELECTION, forceSmsSelection ? 1 : 0);
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.resolve().setForceSmsSelection(forceSmsSelection);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setApproved(@NonNull Recipient recipient, boolean approved) {
|
||||
@@ -253,6 +257,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(APPROVED, approved ? 1 : 0);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setApproved(approved);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setApprovedMe(@NonNull Recipient recipient, boolean approvedMe) {
|
||||
@@ -260,6 +265,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(APPROVED_ME, approvedMe ? 1 : 0);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setHasApprovedMe(approvedMe);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setBlocked(@NonNull Recipient recipient, boolean blocked) {
|
||||
@@ -267,6 +273,24 @@ public class RecipientDatabase extends Database {
|
||||
values.put(BLOCK, blocked ? 1 : 0);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setBlocked(blocked);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setBlocked(@NonNull List<Recipient> recipients, boolean blocked) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(BLOCK, blocked ? 1 : 0);
|
||||
for (Recipient recipient : recipients) {
|
||||
db.update(TABLE_NAME, values, ADDRESS + " = ?", new String[]{recipient.getAddress().serialize()});
|
||||
recipient.resolve().setBlocked(blocked);
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setMuted(@NonNull Recipient recipient, long until) {
|
||||
@@ -274,6 +298,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(MUTE_UNTIL, until);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setMuted(until);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,6 +312,7 @@ public class RecipientDatabase extends Database {
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setNotifyType(notifyType);
|
||||
notifyConversationListListeners();
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setExpireMessages(@NonNull Recipient recipient, int expiration) {
|
||||
@@ -296,6 +322,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(EXPIRE_MESSAGES, expiration);
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setExpireMessages(expiration);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setUnidentifiedAccessMode(@NonNull Recipient recipient, @NonNull UnidentifiedAccessMode unidentifiedAccessMode) {
|
||||
@@ -303,6 +330,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(UNIDENTIFIED_ACCESS_MODE, unidentifiedAccessMode.getMode());
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setUnidentifiedAccessMode(unidentifiedAccessMode);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setProfileKey(@NonNull Recipient recipient, @Nullable byte[] profileKey) {
|
||||
@@ -310,6 +338,7 @@ public class RecipientDatabase extends Database {
|
||||
values.put(PROFILE_KEY, profileKey == null ? null : Base64.encodeBytes(profileKey));
|
||||
updateOrInsert(recipient.getAddress(), values);
|
||||
recipient.resolve().setProfileKey(profileKey);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setProfileAvatar(@NonNull Recipient recipient, @Nullable String profileAvatar) {
|
||||
@@ -317,6 +346,7 @@ public class RecipientDatabase extends Database {
|
||||
contentValues.put(SIGNAL_PROFILE_AVATAR, profileAvatar);
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.resolve().setProfileAvatar(profileAvatar);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setProfileName(@NonNull Recipient recipient, @Nullable String profileName) {
|
||||
@@ -325,6 +355,7 @@ public class RecipientDatabase extends Database {
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.resolve().setName(profileName);
|
||||
recipient.resolve().setProfileName(profileName);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setProfileSharing(@NonNull Recipient recipient, boolean enabled) {
|
||||
@@ -332,6 +363,7 @@ public class RecipientDatabase extends Database {
|
||||
contentValues.put(PROFILE_SHARING, enabled ? 1 : 0);
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.setProfileSharing(enabled);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setNotificationChannel(@NonNull Recipient recipient, @Nullable String notificationChannel) {
|
||||
@@ -339,6 +371,7 @@ public class RecipientDatabase extends Database {
|
||||
contentValues.put(NOTIFICATION_CHANNEL, notificationChannel);
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.setNotificationChannel(notificationChannel);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
public void setRegistered(@NonNull Recipient recipient, RegisteredState registeredState) {
|
||||
@@ -346,6 +379,7 @@ public class RecipientDatabase extends Database {
|
||||
contentValues.put(REGISTERED, registeredState.getId());
|
||||
updateOrInsert(recipient.getAddress(), contentValues);
|
||||
recipient.setRegistered(registeredState);
|
||||
notifyRecipientListeners();
|
||||
}
|
||||
|
||||
private void updateOrInsert(Address address, ContentValues contentValues) {
|
||||
@@ -365,6 +399,22 @@ public class RecipientDatabase extends Database {
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
public List<Recipient> getBlockedContacts() {
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
|
||||
Cursor cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS}, BLOCK + " = 1",
|
||||
null, null, null, null, null);
|
||||
|
||||
RecipientReader reader = new RecipientReader(context, cursor);
|
||||
List<Recipient> returnList = new ArrayList<>();
|
||||
Recipient current;
|
||||
while ((current = reader.getNext()) != null) {
|
||||
returnList.add(current);
|
||||
}
|
||||
reader.close();
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static class RecipientReader implements Closeable {
|
||||
|
||||
private final Context context;
|
||||
|
||||
@@ -952,4 +952,14 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
||||
DatabaseComponent.get(context).reactionDatabase().deleteMessageReactions(MessageId(messageId, mms))
|
||||
}
|
||||
|
||||
override fun unblock(toUnblock: List<Recipient>) {
|
||||
val recipientDb = DatabaseComponent.get(context).recipientDatabase()
|
||||
recipientDb.setBlocked(toUnblock, false)
|
||||
}
|
||||
|
||||
override fun blockedContacts(): List<Recipient> {
|
||||
val recipientDb = DatabaseComponent.get(context).recipientDatabase()
|
||||
return recipientDb.blockedContacts
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,6 +50,7 @@ public class ThreadRecord extends DisplayRecord {
|
||||
private final long expiresIn;
|
||||
private final long lastSeen;
|
||||
private final boolean pinned;
|
||||
private final int recipientHash;
|
||||
|
||||
public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri,
|
||||
@NonNull Recipient recipient, long date, long count, int unreadCount,
|
||||
@@ -65,13 +66,18 @@ public class ThreadRecord extends DisplayRecord {
|
||||
this.archived = archived;
|
||||
this.expiresIn = expiresIn;
|
||||
this.lastSeen = lastSeen;
|
||||
this.pinned = pinned;
|
||||
this.pinned = pinned;
|
||||
this.recipientHash = recipient.hashCode();
|
||||
}
|
||||
|
||||
public @Nullable Uri getSnippetUri() {
|
||||
return snippetUri;
|
||||
}
|
||||
|
||||
public int getRecipientHash() {
|
||||
return recipientHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpannableString getDisplayBody(@NonNull Context context) {
|
||||
if (isGroupUpdateMessage()) {
|
||||
|
||||
Reference in New Issue
Block a user