wip: new status message dialog

This commit is contained in:
Daniel Gultsch 2018-03-03 12:27:46 +01:00
parent 57bcf824e9
commit 2f71c0cb79
10 changed files with 242 additions and 42 deletions

View file

@ -73,4 +73,9 @@ public class PresenceTemplate extends AbstractEntity {
result = 31 * result + status.hashCode(); result = 31 * result + status.hashCode();
return result; return result;
} }
@Override
public String toString() {
return statusMessage;
}
} }

View file

@ -852,22 +852,16 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
} }
} }
Account account = message.getConversation().getAccount(); Account account = message.getConversation().getAccount();
Intent intent; Intent intent = new Intent(activity, EditAccountActivity.class);
if (activity.manuallyChangePresence() && !received) { intent.putExtra("jid", account.getJid().toBareJid().toString());
intent = new Intent(activity, SetPresenceActivity.class); String fingerprint;
intent.putExtra(EXTRA_ACCOUNT, account.getJid().toBareJid().toString()); if (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
fingerprint = "pgp";
} else { } else {
intent = new Intent(activity, EditAccountActivity.class); fingerprint = message.getFingerprint();
intent.putExtra("jid", account.getJid().toBareJid().toString());
String fingerprint;
if (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
fingerprint = "pgp";
} else {
fingerprint = message.getFingerprint();
}
intent.putExtra("fingerprint", fingerprint);
} }
intent.putExtra("fingerprint", fingerprint);
startActivity(intent); startActivity(intent);
}); });
messageListAdapter.setOnContactPictureLongClicked(message -> { messageListAdapter.setOnContactPictureLongClicked(message -> {

View file

@ -10,6 +10,7 @@ import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Settings; import android.provider.Settings;
import android.security.KeyChain; import android.security.KeyChain;
import android.security.KeyChainAliasCallback; import android.security.KeyChainAliasCallback;
@ -20,10 +21,12 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.app.AlertDialog.Builder; import android.support.v7.app.AlertDialog.Builder;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
@ -52,12 +55,15 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.databinding.ActivityEditAccountBinding; import eu.siacs.conversations.databinding.ActivityEditAccountBinding;
import eu.siacs.conversations.databinding.DialogPresenceBinding;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.PresenceTemplate;
import eu.siacs.conversations.services.BarcodeProvider; import eu.siacs.conversations.services.BarcodeProvider;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested; import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.PresenceTemplateAdapter;
import eu.siacs.conversations.ui.widget.DisabledActionModeCallback; import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
@ -622,7 +628,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
changePassword.setVisible(false); changePassword.setVisible(false);
} }
mamPrefs.setVisible(mAccount.getXmppConnection().getFeatures().mam()); mamPrefs.setVisible(mAccount.getXmppConnection().getFeatures().mam());
changePresence.setVisible(manuallyChangePresence()); changePresence.setVisible(true);
} else { } else {
showBlocklist.setVisible(false); showBlocklist.setVisible(false);
showMoreInfo.setVisible(false); showMoreInfo.setVisible(false);
@ -833,9 +839,23 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
} }
private void changePresence() { private void changePresence() {
Intent intent = new Intent(this, SetPresenceActivity.class); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
intent.putExtra(SetPresenceActivity.EXTRA_ACCOUNT, mAccount.getJid().toBareJid().toString()); boolean manualStatus = sharedPreferences.getBoolean(SettingsActivity.MANUALLY_CHANGE_PRESENCE, getResources().getBoolean(R.bool.manually_change_presence));
startActivity(intent); AlertDialog.Builder builder = new AlertDialog.Builder(this);
final DialogPresenceBinding binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.dialog_presence,null,false);
binding.show.setVisibility(manualStatus ? View.VISIBLE : View.GONE);
List<PresenceTemplate> templates = xmppConnectionService.getPresenceTemplates(mAccount);
PresenceTemplateAdapter presenceTemplateAdapter = new PresenceTemplateAdapter(this,R.layout.simple_list_item,templates);
binding.statusMessage.setAdapter(presenceTemplateAdapter);
binding.statusMessage.setOnItemClickListener((parent, view, position, id) -> {
PresenceTemplate template = (PresenceTemplate) parent.getItemAtPosition(position);
Log.d(Config.LOGTAG,"selected: "+template.getStatusMessage());
});
builder.setTitle(R.string.change_presence);
builder.setView(binding.getRoot());
builder.setNegativeButton(R.string.cancel,null);
builder.setPositiveButton(R.string.confirm,null);
builder.create().show();
} }
@Override @Override

View file

@ -128,12 +128,10 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
if (this.selectedAccount.isEnabled()) { if (this.selectedAccount.isEnabled()) {
menu.findItem(R.id.mgmt_account_enable).setVisible(false); menu.findItem(R.id.mgmt_account_enable).setVisible(false);
menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(Config.supportOpenPgp()); menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(Config.supportOpenPgp());
menu.findItem(R.id.mgmt_account_change_presence).setVisible(manuallyChangePresence());
} else { } else {
menu.findItem(R.id.mgmt_account_disable).setVisible(false); menu.findItem(R.id.mgmt_account_disable).setVisible(false);
menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false); menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false);
menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false); menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false);
menu.findItem(R.id.mgmt_account_change_presence).setVisible(false);
} }
menu.setHeaderTitle(this.selectedAccount.getJid().toBareJid().toString()); menu.setHeaderTitle(this.selectedAccount.getJid().toBareJid().toString());
} }
@ -194,9 +192,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
case R.id.mgmt_account_announce_pgp: case R.id.mgmt_account_announce_pgp:
publishOpenPGPPublicKey(selectedAccount); publishOpenPGPPublicKey(selectedAccount);
return true; return true;
case R.id.mgmt_account_change_presence:
changePresence(selectedAccount);
return true;
default: default:
return super.onContextItemSelected(item); return super.onContextItemSelected(item);
} }
@ -245,12 +240,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
} }
} }
private void changePresence(Account account) {
Intent intent = new Intent(this, SetPresenceActivity.class);
intent.putExtra(SetPresenceActivity.EXTRA_ACCOUNT,account.getJid().toBareJid().toString());
startActivity(intent);
}
public void onClickTglAccountState(Account account, boolean enable) { public void onClickTglAccountState(Account account, boolean enable) {
if (enable) { if (enable) {
enableAccount(account); enableAccount(account);

View file

@ -1,6 +1,7 @@
package eu.siacs.conversations.ui.adapter; package eu.siacs.conversations.ui.adapter;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Filter; import android.widget.Filter;
@ -45,10 +46,9 @@ public class KnownHostsAdapter extends ArrayAdapter<String> {
} }
@Override @Override
protected void publishResults(CharSequence constraint, protected void publishResults(CharSequence constraint, FilterResults results) {
FilterResults results) {
ArrayList filteredList = (ArrayList) results.values; ArrayList filteredList = (ArrayList) results.values;
if (results != null && results.count > 0) { if (results.count > 0) {
clear(); clear();
for (Object c : filteredList) { for (Object c : filteredList) {
add((String) c); add((String) c);
@ -59,11 +59,12 @@ public class KnownHostsAdapter extends ArrayAdapter<String> {
}; };
public KnownHostsAdapter(Context context, int viewResourceId, List<String> mKnownHosts) { public KnownHostsAdapter(Context context, int viewResourceId, List<String> mKnownHosts) {
super(context, viewResourceId, new ArrayList<String>()); super(context, viewResourceId, new ArrayList<>());
domains = new ArrayList<>(mKnownHosts); domains = new ArrayList<>(mKnownHosts);
} }
@Override @Override
@NonNull
public Filter getFilter() { public Filter getFilter() {
return domainFilter; return domainFilter;
} }

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2018, Daniel Gultsch All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package eu.siacs.conversations.ui.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import eu.siacs.conversations.entities.PresenceTemplate;
public class PresenceTemplateAdapter extends ArrayAdapter<PresenceTemplate> {
private final List<PresenceTemplate> templates;
private final Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = new ArrayList<>(templates);
results.count = templates.size();
} else {
ArrayList<PresenceTemplate> suggestions = new ArrayList<>();
final String needle = constraint.toString().trim().toLowerCase(Locale.getDefault());
for(PresenceTemplate template : templates) {
final String lc = template.getStatusMessage().toLowerCase(Locale.getDefault());
if (needle.isEmpty() || lc.contains(needle)) {
suggestions.add(template);
}
}
results.values = suggestions;
results.count = suggestions.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList filteredList = (ArrayList) results.values;
clear();
for (Object c : filteredList) {
add((PresenceTemplate) c);
}
notifyDataSetChanged();
}
};
public PresenceTemplateAdapter(@NonNull Context context, int resource, @NonNull List<PresenceTemplate> templates) {
super(context, resource, new ArrayList<>());
this.templates = new ArrayList<>(templates);
}
@Override
@NonNull
public Filter getFilter() {
return this.filter;
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018, Daniel Gultsch All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package eu.siacs.conversations.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
public class ImmediateAutoCompleteTextView extends android.support.v7.widget.AppCompatAutoCompleteTextView {
public ImmediateAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImmediateAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean enoughToFilter() {
return true;
}
}

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="?attr/dialog_horizontal_padding"
android:paddingRight="?attr/dialog_horizontal_padding"
android:paddingBottom="?attr/dialog_vertical_padding"
android:paddingTop="?attr/dialog_vertical_padding">
<RadioGroup
android:id="@+id/show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="?attr/dialog_vertical_padding">
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/presence_online"/>
<RadioButton
android:id="@+id/radioButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/presence_away"/>
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/presence_xa"/>
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/presence_dnd"/>
</RadioGroup>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<eu.siacs.conversations.ui.widget.ImmediateAutoCompleteTextView
android:id="@+id/status_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/status_message"
android:inputType="textPersonName"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</layout>

View file

@ -1,6 +1,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_change_presence"
android:icon="@drawable/ic_announcement_white_24dp"
app:showAsAction="always"
android:title="@string/change_presence"/>
<item <item
android:id="@+id/action_share" android:id="@+id/action_share"
android:icon="?attr/icon_share" android:icon="?attr/icon_share"
@ -22,12 +28,6 @@
</menu> </menu>
</item> </item>
<item
android:id="@+id/action_change_presence"
android:icon="@drawable/ic_announcement_white_24dp"
app:showAsAction="always"
android:title="@string/change_presence"/>
<item <item
android:id="@+id/action_show_block_list" android:id="@+id/action_show_block_list"
app:showAsAction="never" app:showAsAction="never"

View file

@ -5,9 +5,6 @@
<item <item
android:id="@+id/mgmt_account_enable" android:id="@+id/mgmt_account_enable"
android:title="@string/mgmt_account_enable"/> android:title="@string/mgmt_account_enable"/>
<item
android:id="@+id/mgmt_account_change_presence"
android:title="@string/change_presence"/>
<item <item
android:id="@+id/mgmt_account_publish_avatar" android:id="@+id/mgmt_account_publish_avatar"
android:title="@string/mgmt_account_publish_avatar"/> android:title="@string/mgmt_account_publish_avatar"/>