mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| deb4e356bd | |||
| 88d6992a9e | |||
| 5e6b09031a | |||
| 115ebf52b6 |
@@ -360,7 +360,6 @@
|
||||
<activity android:name=".WebxdcActivity"
|
||||
android:label=""
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:windowSoftInputMode="adjustPan"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode">
|
||||
</activity>
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Activity container for selecting a list of contacts.
|
||||
@@ -34,6 +36,9 @@ import java.util.List;
|
||||
public class ContactMultiSelectionActivity extends ContactSelectionActivity {
|
||||
|
||||
public static final String CONTACTS_EXTRA = "contacts_extra";
|
||||
public static final String REMOVED_CONTACTS_EXTRA = "removed_contacts_extra";
|
||||
|
||||
private ArrayList<Integer> preselectedContacts;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle, boolean ready) {
|
||||
@@ -44,6 +49,9 @@ public class ContactMultiSelectionActivity extends ContactSelectionActivity {
|
||||
// it's a bit confusing having one "X" button on the left and one on the right -
|
||||
// and the "clear search" button is not that important.
|
||||
getToolbar().setUseClearButton(false);
|
||||
|
||||
// Store preselected contacts to track which ones were removed
|
||||
preselectedContacts = getIntent().getIntegerArrayListExtra(ContactSelectionListFragment.PRESELECTED_CONTACTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,6 +80,19 @@ public class ContactMultiSelectionActivity extends ContactSelectionActivity {
|
||||
Intent resultIntent = getIntent();
|
||||
List<Integer> selectedContacts = contactsFragment.getSelectedContacts();
|
||||
resultIntent.putIntegerArrayListExtra(CONTACTS_EXTRA, new ArrayList<>(selectedContacts));
|
||||
|
||||
// Calculate which contacts were removed (preselected but not in final selection)
|
||||
if (preselectedContacts != null) {
|
||||
Set<Integer> selectedSet = new HashSet<>(selectedContacts);
|
||||
ArrayList<Integer> removedContacts = new ArrayList<>();
|
||||
for (Integer preselectedId : preselectedContacts) {
|
||||
if (!selectedSet.contains(preselectedId)) {
|
||||
removedContacts.add(preselectedId);
|
||||
}
|
||||
}
|
||||
resultIntent.putIntegerArrayListExtra(REMOVED_CONTACTS_EXTRA, removedContacts);
|
||||
}
|
||||
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,13 +310,24 @@ public class ProfileFragment extends Fragment
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode==REQUEST_CODE_PICK_CONTACT && resultCode==Activity.RESULT_OK && data!=null) {
|
||||
List<Integer> selected = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.CONTACTS_EXTRA);
|
||||
List<Integer> removed = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.REMOVED_CONTACTS_EXTRA);
|
||||
if(selected == null) return;
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
// Add new members
|
||||
for (Integer contactId : selected) {
|
||||
if (contactId!=null) {
|
||||
if (contactId != null) {
|
||||
dcContext.addContactToChat(chatId, contactId);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove members that were explicitly unchecked
|
||||
if (removed != null) {
|
||||
for (Integer contactId : removed) {
|
||||
if (contactId != null) {
|
||||
dcContext.removeContactFromChat(chatId, contactId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity
|
||||
findViewById(R.id.status_bar_background).setBackgroundResource(R.drawable.search_toolbar_shadow);
|
||||
} else {
|
||||
// add padding to avoid content hidden behind system bars
|
||||
// Use applyWindowInsetsExcludingIme to respect navigation bars but not keyboard
|
||||
ViewUtil.applyWindowInsetsExcludingIme(findViewById(R.id.content_container));
|
||||
ViewUtil.applyWindowInsets(findViewById(R.id.content_container));
|
||||
}
|
||||
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
|
||||
@@ -316,23 +316,6 @@ public class ViewUtil {
|
||||
return Insets.max(systemBars, displayCutout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get combined insets from status bar, navigation bar and display cutout areas,
|
||||
* excluding the IME (soft keyboard).
|
||||
*
|
||||
* @param windowInsets The window insets to extract from
|
||||
* @return Combined insets excluding IME
|
||||
*/
|
||||
private static Insets getCombinedInsetsExcludingIme(@NonNull WindowInsetsCompat windowInsets) {
|
||||
Insets systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
Insets displayCutout = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout());
|
||||
|
||||
// Combine systemBars (which excludes IME) with displayCutout using max to handle notches/cutouts
|
||||
Insets combined = Insets.max(systemBars, displayCutout);
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply window insets to a view by adding margin to avoid drawing it behind system bars.
|
||||
* Convenience method that applies insets to all sides.
|
||||
@@ -468,67 +451,6 @@ public class ViewUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply window insets to a view by adding padding to avoid drawing elements behind system bars,
|
||||
* excluding IME (soft keyboard) insets. This is useful for views that should respect navigation
|
||||
* bars but handle keyboard resizing through the window's soft input mode.
|
||||
*
|
||||
* This method stores the original padding values in view tags to ensure that
|
||||
* padding doesn't accumulate on multiple inset applications.
|
||||
*
|
||||
* Note: This feature is only enabled on API 30+ (Android 11+) where WindowInsets APIs
|
||||
* work correctly. On older API levels, the method returns early and the view will use
|
||||
* default system bar handling (content may be drawn behind system bars).
|
||||
*
|
||||
* @param view The view to apply insets to
|
||||
*/
|
||||
public static void applyWindowInsetsExcludingIme(@NonNull View view) {
|
||||
// Only enable on API 30+ where WindowInsets APIs work correctly
|
||||
if (!isEdgeToEdgeSupported()) return;
|
||||
|
||||
// Store the original padding as a tag only if not already stored
|
||||
// This prevents losing the true original padding on subsequent calls
|
||||
if (view.getTag(R.id.tag_window_insets_padding_left) == null) {
|
||||
view.setTag(R.id.tag_window_insets_padding_left, view.getPaddingLeft());
|
||||
view.setTag(R.id.tag_window_insets_padding_top, view.getPaddingTop());
|
||||
view.setTag(R.id.tag_window_insets_padding_right, view.getPaddingRight());
|
||||
view.setTag(R.id.tag_window_insets_padding_bottom, view.getPaddingBottom());
|
||||
}
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
|
||||
Insets insets = getCombinedInsetsExcludingIme(windowInsets);
|
||||
|
||||
// Retrieve the original padding values from tags with null checks
|
||||
Integer leftTag = (Integer) v.getTag(R.id.tag_window_insets_padding_left);
|
||||
Integer topTag = (Integer) v.getTag(R.id.tag_window_insets_padding_top);
|
||||
Integer rightTag = (Integer) v.getTag(R.id.tag_window_insets_padding_right);
|
||||
Integer bottomTag = (Integer) v.getTag(R.id.tag_window_insets_padding_bottom);
|
||||
int basePaddingLeft = leftTag != null ? leftTag : 0;
|
||||
int basePaddingTop = topTag != null ? topTag : 0;
|
||||
int basePaddingRight = rightTag != null ? rightTag : 0;
|
||||
int basePaddingBottom = bottomTag != null ? bottomTag : 0;
|
||||
|
||||
v.setPadding(
|
||||
basePaddingLeft + insets.left,
|
||||
basePaddingTop + insets.top,
|
||||
basePaddingRight + insets.right,
|
||||
basePaddingBottom + insets.bottom
|
||||
);
|
||||
|
||||
// Consume IME insets to prevent them from affecting child views (like WebView)
|
||||
// This stops the double-padding issue where both window resize and inset padding occur
|
||||
WindowInsetsCompat withoutIme = new WindowInsetsCompat.Builder(windowInsets)
|
||||
.setInsets(WindowInsetsCompat.Type.ime(), Insets.NONE)
|
||||
.build();
|
||||
return withoutIme;
|
||||
});
|
||||
|
||||
// Request the initial insets to be dispatched if the view is attached
|
||||
if (view.isAttachedToWindow()) {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the top status bar inset as the height of a view.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user