Merge branch 'development' of https://github.com/siacs/Conversations into development
@ -48,6 +48,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="eu.siacs.conversations.ui.StartConversation"
|
||||
android:label="@string/title_activity_start_conversation"
|
||||
android:parentActivityName="eu.siacs.conversations.ui.ConversationActivity"
|
||||
android:logo="@drawable/ic_activity"
|
||||
></activity>
|
||||
<activity
|
||||
android:name="eu.siacs.conversations.ui.SettingsActivity"
|
||||
android:label="@string/title_activity_settings"
|
||||
|
BIN
libs/android-support-v13.jar
Normal file
BIN
res/drawable-hdpi/tab_selected_conversations.9.png
Normal file
After Width: | Height: | Size: 99 B |
BIN
res/drawable-hdpi/tab_selected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 99 B |
BIN
res/drawable-hdpi/tab_selected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
res/drawable-hdpi/tab_unselected_conversations.9.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
res/drawable-hdpi/tab_unselected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 93 B |
BIN
res/drawable-hdpi/tab_unselected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 100 B |
BIN
res/drawable-mdpi/tab_selected_conversations.9.png
Normal file
After Width: | Height: | Size: 96 B |
BIN
res/drawable-mdpi/tab_selected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 96 B |
BIN
res/drawable-mdpi/tab_selected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 102 B |
BIN
res/drawable-mdpi/tab_unselected_conversations.9.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
res/drawable-mdpi/tab_unselected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 90 B |
BIN
res/drawable-mdpi/tab_unselected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 97 B |
BIN
res/drawable-xhdpi/tab_selected_conversations.9.png
Normal file
After Width: | Height: | Size: 104 B |
BIN
res/drawable-xhdpi/tab_selected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 103 B |
BIN
res/drawable-xhdpi/tab_selected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
res/drawable-xhdpi/tab_unselected_conversations.9.png
Normal file
After Width: | Height: | Size: 112 B |
BIN
res/drawable-xhdpi/tab_unselected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 93 B |
BIN
res/drawable-xhdpi/tab_unselected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
res/drawable-xxhdpi/tab_selected_conversations.9.png
Normal file
After Width: | Height: | Size: 108 B |
BIN
res/drawable-xxhdpi/tab_selected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 108 B |
BIN
res/drawable-xxhdpi/tab_selected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 114 B |
BIN
res/drawable-xxhdpi/tab_unselected_conversations.9.png
Normal file
After Width: | Height: | Size: 109 B |
BIN
res/drawable-xxhdpi/tab_unselected_focused_conversations.9.png
Normal file
After Width: | Height: | Size: 95 B |
BIN
res/drawable-xxhdpi/tab_unselected_pressed_conversations.9.png
Normal file
After Width: | Height: | Size: 102 B |
19
res/drawable/actionbar_tab_indicator.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Non focused states -->
|
||||
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@android:color/transparent" />
|
||||
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_conversations" />
|
||||
|
||||
<!-- Focused states -->
|
||||
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_conversations" />
|
||||
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_conversations" />
|
||||
|
||||
<!-- Pressed -->
|
||||
<!-- Non focused states -->
|
||||
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_conversations" />
|
||||
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_conversations" />
|
||||
|
||||
<!-- Focused states -->
|
||||
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_conversations" />
|
||||
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_conversations" />
|
||||
</selector>
|
6
res/drawable/snackbar.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/darkbackground"/>
|
||||
<corners android:radius="8dip"/>
|
||||
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
|
||||
</shape>
|
8
res/layout/activity_start_conversation.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/start_conversation_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/primarybackground">
|
||||
|
||||
</android.support.v4.view.ViewPager>
|
37
res/layout/create_contact_dialog.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/your_account"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/primarytext"
|
||||
android:text="@string/your_account" />
|
||||
<Spinner
|
||||
android:id="@+id/account"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/jabber_id"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/primarytext"
|
||||
android:text="@string/account_settings_jabber_id" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/jid"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress"
|
||||
android:hint="@string/account_settings_example_jabber_id"
|
||||
/>
|
||||
</LinearLayout>
|
@ -5,13 +5,31 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/secondarybackground" >
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/textsend"
|
||||
|
||||
|
||||
<ListView
|
||||
android:id="@+id/messages_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_above="@+id/snackbar"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:background="@color/primarybackground" >
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@color/secondarybackground"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:listSelector="@android:color/transparent"
|
||||
android:stackFromBottom="true"
|
||||
android:transcriptMode="normal"
|
||||
tools:listitem="@layout/message_sent" >
|
||||
</ListView>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/textsend"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:background="@color/primarybackground" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/textinput"
|
||||
@ -43,53 +61,42 @@
|
||||
android:src="@drawable/ic_action_send_now" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/messages_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/textsend"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/snackbar"
|
||||
android:background="@color/secondarybackground"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:listSelector="@android:color/transparent"
|
||||
android:stackFromBottom="true"
|
||||
android:transcriptMode="normal"
|
||||
tools:listitem="@layout/message_sent" >
|
||||
</ListView>
|
||||
<RelativeLayout
|
||||
android:id="@+id/snackbar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/textsend"
|
||||
android:background="@drawable/snackbar"
|
||||
android:minHeight="48dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:visibility="gone" >
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/snackbar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:background="@color/darkbackground"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/snackbar_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingLeft="24dp"
|
||||
android:textColor="@color/ondarktext"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/snackbar_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/ondarktext"
|
||||
android:paddingLeft="24dp"/>
|
||||
<TextView
|
||||
android:id="@+id/snackbar_action"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/ondarktext"
|
||||
android:textStyle="bold"
|
||||
android:textAllCaps="true"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingBottom="18dp"/>
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/snackbar_action"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="16dp"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/ondarktext"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
14
res/menu/contact_context.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item
|
||||
android:id="@+id/context_start_conversation"
|
||||
android:title="@string/start_conversation"/>
|
||||
<item
|
||||
android:id="@+id/context_contact_details"
|
||||
android:title="@string/view_contact_details"/>
|
||||
<item
|
||||
android:id="@+id/context_delete_contact"
|
||||
android:title="@string/delete_contact"/>
|
||||
|
||||
</menu>
|
33
res/menu/start_conversation.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:actionViewClass="android.widget.SearchView"
|
||||
android:icon="@drawable/ic_action_search"
|
||||
android:showAsAction="collapseActionView|always"
|
||||
android:title="@string/search"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_create_contact"
|
||||
android:icon="@drawable/ic_action_add_person"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/create_contact"/>
|
||||
<item
|
||||
android:id="@+id/action_create_conference"
|
||||
android:icon="@drawable/ic_action_add_group"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/create_conference"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_accounts"
|
||||
android:orderInCategory="90"
|
||||
android:showAsAction="never"
|
||||
android:title="@string/action_accounts"/>
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="never"
|
||||
android:title="@string/action_settings"/>
|
||||
|
||||
</menu>
|
@ -21,6 +21,7 @@
|
||||
<string name="title_activity_contact_details">Contact Details</string>
|
||||
<string name="title_activity_conversations">Conversations</string>
|
||||
<string name="title_activity_sharewith">Share with Conversation</string>
|
||||
<string name="title_activity_start_conversation">Start Conversation</string>
|
||||
<string name="just_now">just now</string>
|
||||
<string name="minute_ago">1 min ago</string>
|
||||
<string name="minutes_ago">%d mins ago</string>
|
||||
@ -200,10 +201,10 @@
|
||||
<string name="mgmt_account_account_offline">Account is offline</string>
|
||||
<string name="attach_record_voice">Record voice</string>
|
||||
<string name="account_settings">Account Settings</string>
|
||||
<string name="account_settings_jabber_id">Jabber ID:</string>
|
||||
<string name="account_settings_password">Password:</string>
|
||||
<string name="account_settings_jabber_id">Jabber ID</string>
|
||||
<string name="account_settings_password">Password</string>
|
||||
<string name="account_settings_example_jabber_id">username@example.com</string>
|
||||
<string name="account_settings_confirm_password">Confirm password:</string>
|
||||
<string name="account_settings_confirm_password">Confirm password</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="confirm_password">Confirm password</string>
|
||||
<string name="passwords_do_not_match">Passwords do not match</string>
|
||||
@ -254,4 +255,12 @@
|
||||
<string name="otr_fingerprint">OTR fingerprint</string>
|
||||
<string name="verify">Verify</string>
|
||||
<string name="decrypt">Decrypt</string>
|
||||
<string name="conferences">Conferences</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="create_contact">Create Contact</string>
|
||||
<string name="create_conference">Create Conference</string>
|
||||
<string name="delete_contact">Delete Contact</string>
|
||||
<string name="view_contact_details">View contact details</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="contact_already_exists">The contact already exists</string>
|
||||
</resources>
|
@ -1,23 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="ConversationsTheme"
|
||||
parent="@android:style/Theme.Holo.Light.DarkActionBar">
|
||||
|
||||
<style name="ConversationsTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
|
||||
<item name="android:actionBarStyle">@style/ConversationsActionBar</item>
|
||||
<item name="android:actionBarWidgetTheme">@style/ConversationsActionBarWidget</item>
|
||||
<item name="android:actionBarTabStyle">@style/ConversationsActionBarTabs</item>
|
||||
</style>
|
||||
|
||||
<style name="ConversationsActionBar"
|
||||
parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
|
||||
<style name="ConversationsActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
|
||||
<item name="android:background">#259b24</item>
|
||||
<item name="android:backgroundStacked">#0a7e07</item>
|
||||
<item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
|
||||
<item name="android:icon">@android:color/transparent</item>
|
||||
<item name="android:icon">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<style name="ConversationsActionBarWidget" parent="android:Theme.Holo.Light">
|
||||
<item name="android:popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
|
||||
<item name="android:dropDownListViewStyle">@android:style/Widget.Holo.Light.ListView.DropDown</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="ConversationsActionBarWidget"
|
||||
parent="android:Theme.Holo.Light">
|
||||
<item name="android:popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
|
||||
<item name="android:dropDownListViewStyle">@android:style/Widget.Holo.Light.ListView.DropDown</item>
|
||||
</style>
|
||||
</resources>
|
||||
<style name="ConversationsActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView">
|
||||
<item name="android:background">@drawable/actionbar_tab_indicator</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -12,7 +12,7 @@ import eu.siacs.conversations.xml.Element;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
|
||||
public class Contact {
|
||||
public class Contact implements ListItem {
|
||||
public static final String TABLENAME = "contacts";
|
||||
|
||||
public static final String SYSTEMNAME = "systemname";
|
||||
@ -37,7 +37,7 @@ public class Contact {
|
||||
protected Account account;
|
||||
|
||||
protected boolean inRoster = true;
|
||||
|
||||
|
||||
public Lastseen lastseen = new Lastseen();
|
||||
|
||||
public Contact(String account, String systemName, String serverName,
|
||||
@ -83,8 +83,10 @@ public class Contact {
|
||||
}
|
||||
|
||||
public boolean match(String needle) {
|
||||
return (jid.toLowerCase().contains(needle.toLowerCase()) || (getDisplayName()
|
||||
.toLowerCase().contains(needle.toLowerCase())));
|
||||
return needle == null
|
||||
|| jid.contains(needle.toLowerCase())
|
||||
|| getDisplayName().toLowerCase()
|
||||
.contains(needle.toLowerCase());
|
||||
}
|
||||
|
||||
public ContentValues getContentValues() {
|
||||
@ -142,8 +144,8 @@ public class Contact {
|
||||
|| domainParts[0].equals("room")
|
||||
|| domainParts[0].equals("muc")
|
||||
|| domainParts[0].equals("chat")
|
||||
|| domainParts[0].equals("sala")
|
||||
|| domainParts[0].equals("salas"));
|
||||
|| domainParts[0].equals("sala") || domainParts[0]
|
||||
.equals("salas"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,9 +310,14 @@ public class Contact {
|
||||
public static final int DIRTY_PUSH = 6;
|
||||
public static final int DIRTY_DELETE = 7;
|
||||
}
|
||||
|
||||
|
||||
public class Lastseen {
|
||||
public long time = 0;
|
||||
public String presence = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ListItem another) {
|
||||
return this.getDisplayName().compareToIgnoreCase(another.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
7
src/eu/siacs/conversations/entities/ListItem.java
Normal file
@ -0,0 +1,7 @@
|
||||
package eu.siacs.conversations.entities;
|
||||
|
||||
public interface ListItem extends Comparable<ListItem> {
|
||||
public String getDisplayName();
|
||||
public String getJid();
|
||||
public String getProfilePhoto();
|
||||
}
|
@ -1282,6 +1282,7 @@ public class XmppConnectionService extends Service {
|
||||
|
||||
public void deleteContactOnServer(Contact contact) {
|
||||
contact.resetOption(Contact.Options.DIRTY_PUSH);
|
||||
contact.setOption(Contact.Options.DIRTY_DELETE);
|
||||
Account account = contact.getAccount();
|
||||
if (account.getStatus() == Account.STATUS_ONLINE) {
|
||||
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
||||
@ -1290,8 +1291,6 @@ public class XmppConnectionService extends Service {
|
||||
item.setAttribute("subscription", "remove");
|
||||
account.getXmppConnection().sendIqPacket(iq, null);
|
||||
contact.resetOption(Contact.Options.DIRTY_DELETE);
|
||||
} else {
|
||||
contact.setOption(Contact.Options.DIRTY_DELETE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ public class ConversationActivity extends XmppActivity {
|
||||
attachFilePopup.show();
|
||||
break;
|
||||
case R.id.action_add:
|
||||
startActivity(new Intent(this, ContactsActivity.class));
|
||||
startActivity(new Intent(this, StartConversation.class));
|
||||
break;
|
||||
case R.id.action_archive:
|
||||
this.endConversation(getSelectedConversation());
|
||||
@ -496,12 +496,7 @@ public class ConversationActivity extends XmppActivity {
|
||||
case R.id.action_contact_details:
|
||||
Contact contact = this.getSelectedConversation().getContact();
|
||||
if (contact.showInRoster()) {
|
||||
Intent intent = new Intent(this, ContactDetailsActivity.class);
|
||||
intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
|
||||
intent.putExtra("account", this.getSelectedConversation()
|
||||
.getAccount().getJid());
|
||||
intent.putExtra("contact", contact.getJid());
|
||||
startActivity(intent);
|
||||
switchToContactDetails(contact);
|
||||
} else {
|
||||
showAddToRosterDialog(getSelectedConversation());
|
||||
}
|
||||
|
359
src/eu/siacs/conversations/ui/StartConversation.java
Normal file
@ -0,0 +1,359 @@
|
||||
package eu.siacs.conversations.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.ActionBar.Tab;
|
||||
import android.app.ActionBar.TabListener;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.app.ListFragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.v13.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.SpinnerAdapter;
|
||||
import android.widget.SearchView.OnQueryTextListener;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.ListItem;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
import eu.siacs.conversations.utils.Validator;
|
||||
|
||||
public class StartConversation extends XmppActivity {
|
||||
|
||||
private Tab mContactsTab;
|
||||
private Tab mConferencesTab;
|
||||
private ViewPager mViewPager;
|
||||
private SearchView mSearchView;
|
||||
|
||||
private MyListFragment mContactsListFragment = new MyListFragment();
|
||||
private List<ListItem> contacts = new ArrayList<ListItem>();
|
||||
private ArrayAdapter<ListItem> mContactsAdapter;
|
||||
|
||||
private MyListFragment mConferenceListFragment = new MyListFragment();
|
||||
private List<ListItem> conferences = new ArrayList<ListItem>();
|
||||
private ArrayAdapter<ListItem> mConferenceAdapter;
|
||||
|
||||
private List<String> mActivatedAccounts = new ArrayList<String>();
|
||||
|
||||
private TabListener mTabListener = new TabListener() {
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(Tab tab, FragmentTransaction ft) {
|
||||
mViewPager.setCurrentItem(tab.getPosition());
|
||||
onTabChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(Tab tab, FragmentTransaction ft) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
getActionBar().setSelectedNavigationItem(position);
|
||||
onTabChanged();
|
||||
}
|
||||
};
|
||||
private OnQueryTextListener mOnQueryTextListener = new OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
filterContacts(newText);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_start_conversation);
|
||||
mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager);
|
||||
ActionBar actionBar = getActionBar();
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
|
||||
mContactsTab = actionBar.newTab().setText(R.string.contacts)
|
||||
.setTabListener(mTabListener);
|
||||
mConferencesTab = actionBar.newTab().setText(R.string.conferences)
|
||||
.setTabListener(mTabListener);
|
||||
actionBar.addTab(mContactsTab);
|
||||
actionBar.addTab(mConferencesTab);
|
||||
|
||||
mViewPager.setOnPageChangeListener(mOnPageChangeListener);
|
||||
mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
if (position == 0) {
|
||||
return mContactsListFragment;
|
||||
} else {
|
||||
return mConferenceListFragment;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mConferenceAdapter = new ListItemAdapter(conferences);
|
||||
mConferenceListFragment.setListAdapter(mConferenceAdapter);
|
||||
|
||||
mContactsAdapter = new ListItemAdapter(contacts);
|
||||
mContactsListFragment.setListAdapter(mContactsAdapter);
|
||||
mContactsListFragment
|
||||
.setOnListItemClickListener(new OnItemClickListener() {
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1,
|
||||
int position, long arg3) {
|
||||
openConversationForContact(position);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void openConversationForContact(int position) {
|
||||
Contact contact = (Contact) contacts.get(position);
|
||||
Conversation conversation = xmppConnectionService
|
||||
.findOrCreateConversation(contact.getAccount(),
|
||||
contact.getJid(), false);
|
||||
switchToConversation(conversation, null, false);
|
||||
}
|
||||
|
||||
protected void openDetailsForContact(int position) {
|
||||
Contact contact = (Contact) contacts.get(position);
|
||||
switchToContactDetails(contact);
|
||||
}
|
||||
|
||||
protected void deleteContact(int position) {
|
||||
Contact contact = (Contact) contacts.get(position);
|
||||
xmppConnectionService.deleteContactOnServer(contact);
|
||||
filterContacts(null);
|
||||
}
|
||||
|
||||
protected void showCreateContactDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.create_contact);
|
||||
View dialogView = getLayoutInflater().inflate(R.layout.create_contact_dialog, null);
|
||||
final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
|
||||
final EditText jid = (EditText) dialogView.findViewById(R.id.jid);
|
||||
populateAccountSpinner(spinner);
|
||||
builder.setView(dialogView);
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setPositiveButton(R.string.create, null);
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (Validator.isValidJid(jid.getText().toString())) {
|
||||
String accountJid = (String) spinner.getSelectedItem();
|
||||
String contactJid = jid.getText().toString();
|
||||
Account account = xmppConnectionService.findAccountByJid(accountJid);
|
||||
Contact contact = account.getRoster().getContact(contactJid);
|
||||
if (contact.showInRoster()) {
|
||||
jid.setError(getString(R.string.contact_already_exists));
|
||||
} else {
|
||||
xmppConnectionService.createContact(contact);
|
||||
switchToConversation(contact);
|
||||
dialog.dismiss();
|
||||
}
|
||||
} else {
|
||||
jid.setError(getString(R.string.invalid_jid));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void switchToConversation(Contact contact) {
|
||||
Conversation conversation = xmppConnectionService.findOrCreateConversation(contact.getAccount(), contact.getJid(), false);
|
||||
switchToConversation(conversation, null, false);
|
||||
}
|
||||
|
||||
private void populateAccountSpinner(Spinner spinner) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mActivatedAccounts);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.start_conversation, menu);
|
||||
MenuItem menuCreateContact = (MenuItem) menu
|
||||
.findItem(R.id.action_create_contact);
|
||||
MenuItem menuCreateConference = (MenuItem) menu
|
||||
.findItem(R.id.action_create_conference);
|
||||
MenuItem menuSearch = (MenuItem) menu.findItem(R.id.action_search);
|
||||
if (getActionBar().getSelectedNavigationIndex() == 0) {
|
||||
menuCreateConference.setVisible(false);
|
||||
} else {
|
||||
menuCreateContact.setVisible(false);
|
||||
}
|
||||
mSearchView = (SearchView) menuSearch.getActionView();
|
||||
int id = mSearchView.getContext().getResources()
|
||||
.getIdentifier("android:id/search_src_text", null, null);
|
||||
TextView textView = (TextView) mSearchView.findViewById(id);
|
||||
textView.setTextColor(Color.WHITE);
|
||||
mSearchView.setOnQueryTextListener(this.mOnQueryTextListener);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_create_contact:
|
||||
showCreateContactDialog();
|
||||
break;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onBackendConnected() {
|
||||
filterContacts(null);
|
||||
this.mActivatedAccounts.clear();
|
||||
for (Account account : xmppConnectionService.getAccounts()) {
|
||||
if (account.getStatus() != Account.STATUS_DISABLED) {
|
||||
this.mActivatedAccounts.add(account.getJid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void filterContacts(String needle) {
|
||||
this.contacts.clear();
|
||||
for (Account account : xmppConnectionService.getAccounts()) {
|
||||
if (account.getStatus() != Account.STATUS_DISABLED) {
|
||||
for (Contact contact : account.getRoster().getContacts()) {
|
||||
if (contact.showInRoster() && contact.match(needle)) {
|
||||
this.contacts.add(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(this.contacts);
|
||||
mContactsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void onTabChanged() {
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private class ListItemAdapter extends ArrayAdapter<ListItem> {
|
||||
|
||||
public ListItemAdapter(List<ListItem> objects) {
|
||||
super(getApplicationContext(), 0, objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
ListItem item = getItem(position);
|
||||
if (view == null) {
|
||||
view = (View) inflater.inflate(R.layout.contact, null);
|
||||
}
|
||||
TextView name = (TextView) view
|
||||
.findViewById(R.id.contact_display_name);
|
||||
TextView jid = (TextView) view.findViewById(R.id.contact_jid);
|
||||
ImageView picture = (ImageView) view
|
||||
.findViewById(R.id.contact_photo);
|
||||
|
||||
jid.setText(item.getJid());
|
||||
name.setText(item.getDisplayName());
|
||||
picture.setImageBitmap(UIHelper.getContactPicture(item, 48,
|
||||
this.getContext(), false));
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MyListFragment extends ListFragment {
|
||||
private AdapterView.OnItemClickListener mOnItemClickListener;
|
||||
private int mContextPosition = -1;
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (mOnItemClickListener != null) {
|
||||
mOnItemClickListener.onItemClick(l, v, position, id);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
|
||||
this.mOnItemClickListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
registerForContextMenu(getListView());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||
ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
getActivity().getMenuInflater().inflate(R.menu.contact_context,
|
||||
menu);
|
||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
||||
this.mContextPosition = acmi.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
StartConversation activity = (StartConversation) getActivity();
|
||||
switch(item.getItemId()) {
|
||||
case R.id.context_start_conversation:
|
||||
activity.openConversationForContact(mContextPosition);
|
||||
break;
|
||||
case R.id.context_contact_details:
|
||||
activity.openDetailsForContact(mContextPosition);
|
||||
break;
|
||||
case R.id.context_delete_contact:
|
||||
activity.deleteContact(mContextPosition);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -170,6 +170,14 @@ public abstract class XmppActivity extends Activity {
|
||||
}
|
||||
startActivity(viewConversationIntent);
|
||||
}
|
||||
|
||||
public void switchToContactDetails(Contact contact) {
|
||||
Intent intent = new Intent(this, ContactDetailsActivity.class);
|
||||
intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
|
||||
intent.putExtra("account", contact.getAccount().getJid());
|
||||
intent.putExtra("contact", contact.getJid());
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
protected void announcePgp(Account account, final Conversation conversation) {
|
||||
xmppConnectionService.getPgpEngine().generateSignature(account,
|
||||
|
@ -13,11 +13,11 @@ import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.ListItem;
|
||||
import eu.siacs.conversations.entities.Message;
|
||||
import eu.siacs.conversations.entities.MucOptions.User;
|
||||
import eu.siacs.conversations.ui.ConversationActivity;
|
||||
import eu.siacs.conversations.ui.ManageAccountActivity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Notification;
|
||||
@ -239,7 +239,7 @@ public class UIHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap getContactPicture(Contact contact, int dpSize,
|
||||
public static Bitmap getContactPicture(ListItem contact, int dpSize,
|
||||
Context context, boolean notification) {
|
||||
String uri = contact.getProfilePhoto();
|
||||
if (uri == null) {
|
||||
|