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:
Harris
2022-10-12 17:05:55 +11:00
committed by GitHub
parent 92075aed32
commit 7a773016da
378 changed files with 4305 additions and 3062 deletions

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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
}
}

View File

@@ -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()) {