mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 798e5c56aa | |||
| a78cd44857 | |||
| c3e85dc27a | |||
| e36c34a6dc | |||
| 3ffdd2150c | |||
| 57243b50aa | |||
| a42682e1fc |
@@ -240,6 +240,10 @@
|
||||
android:exported="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".TransportListActivity"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".proxy.ProxySettingsActivity"
|
||||
android:label="@string/proxy_settings"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
|
||||
@@ -119,9 +119,20 @@ public class EditTransportActivity extends BaseActionBarActivity implements DcEv
|
||||
});
|
||||
|
||||
EnteredLoginParam config = null;
|
||||
String transportAddr = getIntent().getStringExtra(TransportListActivity.EXTRA_TRANSPORT_ADDR);
|
||||
try {
|
||||
List<EnteredLoginParam> relays = rpc.listTransports(accId);
|
||||
if (!relays.isEmpty()) config = relays.get(0);
|
||||
if (transportAddr != null) {
|
||||
// Find the transport with the specified address
|
||||
for (EnteredLoginParam transport : relays) {
|
||||
if (transportAddr.equals(transport.addr)) {
|
||||
config = transport;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!relays.isEmpty()) {
|
||||
config = relays.get(0);
|
||||
}
|
||||
} catch (RpcException ignored) {}
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import chat.delta.rpc.Rpc;
|
||||
import chat.delta.rpc.RpcException;
|
||||
import chat.delta.rpc.types.EnteredLoginParam;
|
||||
|
||||
public class TransportListActivity extends BaseActionBarActivity
|
||||
implements TransportListAdapter.OnTransportClickListener {
|
||||
|
||||
public static final String EXTRA_TRANSPORT_ADDR = "transport_addr";
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private TransportListAdapter adapter;
|
||||
private FloatingActionButton fabAdd;
|
||||
private Rpc rpc;
|
||||
private int accId;
|
||||
private String mainTransportAddr;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_transport_list);
|
||||
|
||||
rpc = DcHelper.getRpc(this);
|
||||
accId = DcHelper.getContext(this).getAccountId();
|
||||
|
||||
// Setup toolbar
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setTitle(R.string.transports);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
recyclerView = findViewById(R.id.transport_list);
|
||||
fabAdd = findViewById(R.id.fab_add_transport);
|
||||
|
||||
adapter = new TransportListAdapter(this);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
fabAdd.setOnClickListener(v -> openAddTransport());
|
||||
|
||||
// Handle window insets for FAB to stay above navigation bar
|
||||
ViewCompat.setOnApplyWindowInsetsListener(fabAdd, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
CoordinatorLayout.LayoutParams fabParams = (CoordinatorLayout.LayoutParams) fabAdd.getLayoutParams();
|
||||
int fabMargin = (int) (16 * getResources().getDisplayMetrics().density);
|
||||
fabParams.bottomMargin = insets.bottom + fabMargin;
|
||||
fabParams.rightMargin = fabMargin;
|
||||
fabAdd.setLayoutParams(fabParams);
|
||||
return windowInsets;
|
||||
});
|
||||
|
||||
loadTransports();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
loadTransports();
|
||||
}
|
||||
|
||||
private void loadTransports() {
|
||||
Util.runOnBackground(() -> {
|
||||
try {
|
||||
List<EnteredLoginParam> transports = rpc.listTransports(accId);
|
||||
mainTransportAddr = DcHelper.get(this, DcHelper.CONFIG_CONFIGURED_ADDRESS);
|
||||
Util.runOnMain(() -> adapter.setTransports(transports, mainTransportAddr));
|
||||
} catch (RpcException e) {
|
||||
mainTransportAddr = DcHelper.get(this, DcHelper.CONFIG_CONFIGURED_ADDRESS);
|
||||
Util.runOnMain(() -> adapter.setTransports(null, mainTransportAddr));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openAddTransport() {
|
||||
Intent intent = new Intent(this, EditTransportActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransportClick(EnteredLoginParam transport) {
|
||||
// Clicking on a transport makes it the main transport
|
||||
if (transport.addr != null && !transport.addr.equals(mainTransportAddr)) {
|
||||
Util.runOnBackground(() -> {
|
||||
DcHelper.getContext(this).setConfig(DcHelper.CONFIG_CONFIGURED_ADDRESS, transport.addr);
|
||||
Util.runOnMain(this::loadTransports);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransportEdit(EnteredLoginParam transport) {
|
||||
Intent intent = new Intent(this, EditTransportActivity.class);
|
||||
intent.putExtra(EXTRA_TRANSPORT_ADDR, transport.addr);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransportDelete(EnteredLoginParam transport) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.remove_transport)
|
||||
.setMessage(getString(R.string.confirm_remove_transport, transport.addr))
|
||||
.setPositiveButton(R.string.ok, (dialog, which) -> deleteTransport(transport))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void deleteTransport(EnteredLoginParam transport) {
|
||||
Util.runOnBackground(() -> {
|
||||
try {
|
||||
rpc.deleteTransport(accId, transport.addr);
|
||||
Util.runOnMain(this::loadTransports);
|
||||
} catch (RpcException e) {
|
||||
Util.runOnMain(() -> {
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(getString(R.string.error) + ": " + e.getMessage())
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import chat.delta.rpc.types.EnteredLoginParam;
|
||||
|
||||
public class TransportListAdapter extends RecyclerView.Adapter<TransportListAdapter.TransportViewHolder> {
|
||||
|
||||
private List<EnteredLoginParam> transports = new ArrayList<>();
|
||||
private final OnTransportClickListener listener;
|
||||
private String mainTransportAddr;
|
||||
|
||||
public interface OnTransportClickListener {
|
||||
void onTransportClick(EnteredLoginParam transport);
|
||||
void onTransportEdit(EnteredLoginParam transport);
|
||||
void onTransportDelete(EnteredLoginParam transport);
|
||||
}
|
||||
|
||||
public TransportListAdapter(OnTransportClickListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void setTransports(List<EnteredLoginParam> transports, String mainTransportAddr) {
|
||||
this.transports = transports != null ? transports : new ArrayList<>();
|
||||
this.mainTransportAddr = mainTransportAddr;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public TransportViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.transport_list_item, parent, false);
|
||||
return new TransportViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull TransportViewHolder holder, int position) {
|
||||
EnteredLoginParam transport = transports.get(position);
|
||||
boolean isMain = transport.addr != null && transport.addr.equals(mainTransportAddr);
|
||||
holder.bind(transport, isMain, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return transports.size();
|
||||
}
|
||||
|
||||
static class TransportViewHolder extends RecyclerView.ViewHolder {
|
||||
private final TextView emailText;
|
||||
private final TextView serverText;
|
||||
private final ImageView mainIndicator;
|
||||
private final ImageView editButton;
|
||||
private final ImageView deleteButton;
|
||||
|
||||
public TransportViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
emailText = itemView.findViewById(R.id.transport_email);
|
||||
serverText = itemView.findViewById(R.id.transport_server);
|
||||
mainIndicator = itemView.findViewById(R.id.main_transport_indicator);
|
||||
editButton = itemView.findViewById(R.id.edit_button);
|
||||
deleteButton = itemView.findViewById(R.id.delete_button);
|
||||
}
|
||||
|
||||
public void bind(EnteredLoginParam transport, boolean isMain, OnTransportClickListener listener) {
|
||||
emailText.setText(transport.addr);
|
||||
|
||||
String serverInfo = "";
|
||||
if (transport.imapServer != null && !transport.imapServer.isEmpty()) {
|
||||
serverInfo = transport.imapServer;
|
||||
}
|
||||
serverText.setText(serverInfo);
|
||||
serverText.setVisibility(serverInfo.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
|
||||
mainIndicator.setVisibility(isMain ? View.VISIBLE : View.GONE);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onTransportClick(transport);
|
||||
}
|
||||
});
|
||||
|
||||
editButton.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onTransportEdit(transport);
|
||||
}
|
||||
});
|
||||
|
||||
deleteButton.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onTransportDelete(transport);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.ConversationActivity;
|
||||
import org.thoughtcrime.securesms.LogViewActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.EditTransportActivity;
|
||||
import org.thoughtcrime.securesms.TransportListActivity;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.proxy.ProxySettingsActivity;
|
||||
@@ -166,7 +166,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
passwordAndAccount.setOnPreferenceClickListener(((preference) -> {
|
||||
boolean result = ScreenLockUtil.applyScreenLock(requireActivity(), getString(R.string.edit_transport), getString(R.string.enter_system_secret_to_continue), REQUEST_CODE_CONFIRM_CREDENTIALS_ACCOUNT);
|
||||
if (!result) {
|
||||
openRegistrationActivity();
|
||||
openTransportListActivity();
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
@@ -203,7 +203,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_CONFIRM_CREDENTIALS_ACCOUNT) {
|
||||
openRegistrationActivity();
|
||||
openTransportListActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,8 +270,8 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void openRegistrationActivity() {
|
||||
Intent intent = new Intent(requireActivity(), EditTransportActivity.class);
|
||||
private void openTransportListActivity() {
|
||||
Intent intent = new Intent(requireActivity(), TransportListActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="?attr/colorPrimary">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true"
|
||||
app:elevation="0dp">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:contentInsetStart="14dp"
|
||||
app:contentInsetLeft="14dp"
|
||||
android:theme="?attr/actionBarStyle" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/transport_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/transport_list_item" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_add_transport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/add_transport"
|
||||
android:src="@drawable/ic_add_white_24dp" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:minHeight="72dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/main_transport_indicator"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_check_white_24dp"
|
||||
android:tint="?attr/colorPrimary"
|
||||
android:contentDescription="@string/main"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/transport_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="user@example.com" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/transport_server"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:text="imap.example.com" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_create_white_24dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/edit_transport"
|
||||
android:tint="?android:attr/textColorSecondary" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/delete_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_delete_white_24dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/remove_transport"
|
||||
android:tint="?android:attr/textColorSecondary" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -693,6 +693,7 @@
|
||||
<string name="add_transport">Add Transport</string>
|
||||
<string name="remove_transport">Remove Transport</string>
|
||||
<string name="edit_transport">Edit Transport</string>
|
||||
<string name="main">Main</string>
|
||||
<!-- shown if a QR code was scanned that can be used as a transport -->
|
||||
<string name="confirm_add_transport">Add this transport?</string>
|
||||
<string name="invalid_transport_qr">The scanned QR code does not contain a valid transport.</string>
|
||||
|
||||
Reference in New Issue
Block a user