mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-02-14 10:40:55 +01:00
Inital chat support
This commit is contained in:
parent
1c98b381e9
commit
9f2bab7e63
@ -8,5 +8,5 @@
|
|||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-16
|
target=android-17
|
||||||
android.library=true
|
android.library=true
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
a:configChanges="orientation|keyboardHidden"
|
a:configChanges="orientation|keyboardHidden"
|
||||||
a:label="@string/playlist.label"
|
a:label="@string/playlist.label"
|
||||||
a:launchMode="standard" />
|
a:launchMode="standard" />
|
||||||
|
<activity
|
||||||
|
a:name=".activity.ChatActivity"
|
||||||
|
a:configChanges="orientation|keyboardHidden" />
|
||||||
<activity
|
<activity
|
||||||
a:name=".activity.DownloadActivity"
|
a:name=".activity.DownloadActivity"
|
||||||
a:configChanges="keyboardHidden"
|
a:configChanges="keyboardHidden"
|
||||||
|
@ -12,5 +12,5 @@
|
|||||||
|
|
||||||
android.library=true
|
android.library=true
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-16
|
target=android-17
|
||||||
|
|
||||||
|
@ -44,14 +44,14 @@ public final class R {
|
|||||||
public static final class drawable {
|
public static final class drawable {
|
||||||
public static final int default_ptr_flip = 0x7f02000c;
|
public static final int default_ptr_flip = 0x7f02000c;
|
||||||
public static final int default_ptr_rotate = 0x7f02000d;
|
public static final int default_ptr_rotate = 0x7f02000d;
|
||||||
public static final int indicator_arrow = 0x7f020044;
|
public static final int indicator_arrow = 0x7f020048;
|
||||||
public static final int indicator_bg_bottom = 0x7f020045;
|
public static final int indicator_bg_bottom = 0x7f020049;
|
||||||
public static final int indicator_bg_top = 0x7f020046;
|
public static final int indicator_bg_top = 0x7f02004a;
|
||||||
}
|
}
|
||||||
public static final class id {
|
public static final class id {
|
||||||
public static final int both = 0x7f060003;
|
public static final int both = 0x7f060003;
|
||||||
public static final int disabled = 0x7f060000;
|
public static final int disabled = 0x7f060000;
|
||||||
public static final int fl_inner = 0x7f06007e;
|
public static final int fl_inner = 0x7f060086;
|
||||||
public static final int flip = 0x7f060008;
|
public static final int flip = 0x7f060008;
|
||||||
public static final int gridview = 0x7f060009;
|
public static final int gridview = 0x7f060009;
|
||||||
public static final int manualOnly = 0x7f060004;
|
public static final int manualOnly = 0x7f060004;
|
||||||
@ -59,17 +59,17 @@ public final class R {
|
|||||||
public static final int pullFromEnd = 0x7f060002;
|
public static final int pullFromEnd = 0x7f060002;
|
||||||
public static final int pullFromStart = 0x7f060001;
|
public static final int pullFromStart = 0x7f060001;
|
||||||
public static final int pullUpFromBottom = 0x7f060006;
|
public static final int pullUpFromBottom = 0x7f060006;
|
||||||
public static final int pull_to_refresh_image = 0x7f06007f;
|
public static final int pull_to_refresh_image = 0x7f060087;
|
||||||
public static final int pull_to_refresh_progress = 0x7f060080;
|
public static final int pull_to_refresh_progress = 0x7f060088;
|
||||||
public static final int pull_to_refresh_sub_text = 0x7f060082;
|
public static final int pull_to_refresh_sub_text = 0x7f06008a;
|
||||||
public static final int pull_to_refresh_text = 0x7f060081;
|
public static final int pull_to_refresh_text = 0x7f060089;
|
||||||
public static final int rotate = 0x7f060007;
|
public static final int rotate = 0x7f060007;
|
||||||
public static final int scrollview = 0x7f06000b;
|
public static final int scrollview = 0x7f06000b;
|
||||||
public static final int webview = 0x7f06000a;
|
public static final int webview = 0x7f06000a;
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
public static final int pull_to_refresh_header_horizontal = 0x7f030019;
|
public static final int pull_to_refresh_header_horizontal = 0x7f03001c;
|
||||||
public static final int pull_to_refresh_header_vertical = 0x7f03001a;
|
public static final int pull_to_refresh_header_vertical = 0x7f03001d;
|
||||||
}
|
}
|
||||||
public static final class string {
|
public static final class string {
|
||||||
public static final int pull_to_refresh_from_bottom_pull_label = 0x7f080003;
|
public static final int pull_to_refresh_from_bottom_pull_label = 0x7f080003;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,5 +9,6 @@
|
|||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-17
|
target=android-17
|
||||||
android.library.reference.1=android-menudrawer-master\\library
|
android.library=false
|
||||||
|
android.library.reference.1=android-menudrawer-master/library
|
||||||
android.library.reference.2=Android-PullToRefresh/library
|
android.library.reference.2=Android-PullToRefresh/library
|
||||||
|
BIN
res/drawable-xhdpi/ic_menu_chat_dark.png
Normal file
BIN
res/drawable-xhdpi/ic_menu_chat_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-xhdpi/ic_menu_chat_light.png
Normal file
BIN
res/drawable-xhdpi/ic_menu_chat_light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-xhdpi/ic_menu_chat_send_dark.png
Normal file
BIN
res/drawable-xhdpi/ic_menu_chat_send_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
res/drawable-xhdpi/ic_menu_chat_send_light.png
Normal file
BIN
res/drawable-xhdpi/ic_menu_chat_send_light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
50
res/layout/chat.xml
Normal file
50
res/layout/chat.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:orientation="vertical" >
|
||||||
|
|
||||||
|
<include layout="@layout/tab_progress" />
|
||||||
|
|
||||||
|
<com.handmark.pulltorefresh.library.PullToRefreshListView
|
||||||
|
a:id="@+id/chat_entries"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="0dip"
|
||||||
|
a:layout_weight="1.0"
|
||||||
|
a:textFilterEnabled="true" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:layout_height="4dip"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_marginTop="4dip"
|
||||||
|
a:background="@drawable/drop_shadow" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:orientation="horizontal"
|
||||||
|
a:gravity="bottom" >
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
a:id="@+id/chat_edittext"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="40dip"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:autoLink="all"
|
||||||
|
a:hint="@string/chat.send_a_message"
|
||||||
|
a:inputType="textEmailAddress|textMultiLine"
|
||||||
|
a:linksClickable="true"
|
||||||
|
a:paddingBottom="10dip"
|
||||||
|
a:paddingTop="10dip" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
a:id="@+id/chat_send"
|
||||||
|
a:layout_width="60dip"
|
||||||
|
a:layout_height="40dip"
|
||||||
|
a:src="?attr/chat_send" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/now_playing" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
48
res/layout/chat_item.xml
Normal file
48
res/layout/chat_item.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_username"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginLeft="6dip"
|
||||||
|
a:layout_marginRight="6dip"
|
||||||
|
a:ellipsize="marquee"
|
||||||
|
a:singleLine="true"
|
||||||
|
a:text="User"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
a:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:id="@+id/chat_message_layout"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginTop="2dip"
|
||||||
|
a:orientation="horizontal" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_time"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginLeft="6dip"
|
||||||
|
a:singleLine="true"
|
||||||
|
a:text="00:00"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_message"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginLeft="6dip"
|
||||||
|
a:layout_marginRight="6dip"
|
||||||
|
a:autoLink="all"
|
||||||
|
a:linksClickable="true"
|
||||||
|
a:singleLine="false"
|
||||||
|
a:text="Message Text Goes Here"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
51
res/layout/chat_item_reverse.xml
Normal file
51
res/layout/chat_item_reverse.xml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_username"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginRight="6dip"
|
||||||
|
a:gravity="right"
|
||||||
|
a:layout_gravity="right"
|
||||||
|
a:ellipsize="marquee"
|
||||||
|
a:singleLine="true"
|
||||||
|
a:text="User"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
a:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginTop="2dip"
|
||||||
|
a:orientation="horizontal"
|
||||||
|
a:layout_gravity="right" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_time"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginLeft="6dip"
|
||||||
|
a:singleLine="true"
|
||||||
|
a:gravity="right"
|
||||||
|
a:text="00:00"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
a:id="@+id/chat_message"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_marginLeft="6dip"
|
||||||
|
a:layout_marginRight="6dip"
|
||||||
|
a:autoLink="all"
|
||||||
|
a:linksClickable="true"
|
||||||
|
a:singleLine="false"
|
||||||
|
a:gravity="right"
|
||||||
|
a:text="Chat message"
|
||||||
|
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -48,6 +48,14 @@
|
|||||||
android:drawableLeft="?attr/playlists"
|
android:drawableLeft="?attr/playlists"
|
||||||
android:text="@string/button_bar.playlists" />
|
android:text="@string/button_bar.playlists" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/menu_chat"
|
||||||
|
style="@style/MenuDrawer.Widget.Title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawableLeft="?attr/chat"
|
||||||
|
android:text="@string/button_bar.chat" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/menu_now_playing"
|
android:id="@+id/menu_now_playing"
|
||||||
style="@style/MenuDrawer.Widget.Title"
|
style="@style/MenuDrawer.Widget.Title"
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<string name="button_bar.home">UltraSonic Main</string>
|
<string name="button_bar.home">UltraSonic Main</string>
|
||||||
<string name="button_bar.browse">Media Library</string>
|
<string name="button_bar.browse">Media Library</string>
|
||||||
<string name="button_bar.search">Search</string>
|
<string name="button_bar.search">Search</string>
|
||||||
|
<string name="button_bar.chat">Chat</string>
|
||||||
<string name="button_bar.playlists">Playlists</string>
|
<string name="button_bar.playlists">Playlists</string>
|
||||||
<string name="button_bar.now_playing">Now Playing</string>
|
<string name="button_bar.now_playing">Now Playing</string>
|
||||||
<string name="main.welcome_title">Welcome!</string>
|
<string name="main.welcome_title">Welcome!</string>
|
||||||
@ -312,6 +313,7 @@
|
|||||||
<string name="util.bytes_format.byte">0 B</string>
|
<string name="util.bytes_format.byte">0 B</string>
|
||||||
<string name="util.no_time">-:--</string>
|
<string name="util.no_time">-:--</string>
|
||||||
<string name="util.zero_time">0:00</string>
|
<string name="util.zero_time">0:00</string>
|
||||||
|
<string name="chat.send_a_message">Send a message</string>
|
||||||
|
|
||||||
<plurals name="select_album_n_songs">
|
<plurals name="select_album_n_songs">
|
||||||
<item quantity="zero">No songs</item>
|
<item quantity="zero">No songs</item>
|
||||||
|
@ -82,5 +82,7 @@
|
|||||||
<attr name="media_play_small" format="reference"/>
|
<attr name="media_play_small" format="reference"/>
|
||||||
<attr name="media_stop" format="reference"/>
|
<attr name="media_stop" format="reference"/>
|
||||||
<attr name="media_toggle" format="reference"/>
|
<attr name="media_toggle" format="reference"/>
|
||||||
|
<attr name="chat" format="reference"/>
|
||||||
|
<attr name="chat_send" format="reference" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
<item name="media_play_small">@drawable/ic_stat_play_dark</item>
|
<item name="media_play_small">@drawable/ic_stat_play_dark</item>
|
||||||
<item name="media_stop">@drawable/media_stop_normal_dark</item>
|
<item name="media_stop">@drawable/media_stop_normal_dark</item>
|
||||||
<item name="media_toggle">@drawable/media_toggle_list_normal_dark</item>
|
<item name="media_toggle">@drawable/media_toggle_list_normal_dark</item>
|
||||||
|
<item name="chat">@drawable/ic_menu_chat_dark</item>
|
||||||
|
<item name="chat_send">@drawable/ic_menu_chat_send_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="UltraSonicTheme.Light" parent="@android:style/Theme.Holo.Light">
|
<style name="UltraSonicTheme.Light" parent="@android:style/Theme.Holo.Light">
|
||||||
@ -77,6 +79,8 @@
|
|||||||
<item name="media_play_small">@drawable/ic_stat_play_light</item>
|
<item name="media_play_small">@drawable/ic_stat_play_light</item>
|
||||||
<item name="media_stop">@drawable/media_stop_normal_light</item>
|
<item name="media_stop">@drawable/media_stop_normal_light</item>
|
||||||
<item name="media_toggle">@drawable/media_toggle_list_normal_light</item>
|
<item name="media_toggle">@drawable/media_toggle_list_normal_light</item>
|
||||||
|
<item name="chat">@drawable/ic_menu_chat_light</item>
|
||||||
|
<item name="chat_send">@drawable/ic_menu_chat_send_light</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -0,0 +1,205 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.activity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.service.MusicService;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.service.MusicServiceFactory;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.BackgroundTask;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.Constants;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.TabActivityBackgroundTask;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.Util;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.view.ChatAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Joshua Bahnsen
|
||||||
|
*/
|
||||||
|
public final class ChatActivity extends SubsonicTabActivity {
|
||||||
|
private PullToRefreshListView refreshChatListView;
|
||||||
|
private ListView chatListView;
|
||||||
|
private EditText messageEditText;
|
||||||
|
private ImageButton sendButton;
|
||||||
|
//private ChatAdapter chatAdapter;
|
||||||
|
private static Long lastChatMessageTime = (long) 0;
|
||||||
|
private static ArrayList<ChatMessage> messageList = new ArrayList<ChatMessage>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle bundle) {
|
||||||
|
super.onCreate(bundle);
|
||||||
|
setContentView(R.layout.chat);
|
||||||
|
|
||||||
|
refreshChatListView = (PullToRefreshListView) findViewById(R.id.chat_entries);
|
||||||
|
refreshChatListView.setMode(Mode.PULL_FROM_END);
|
||||||
|
|
||||||
|
messageEditText = (EditText) findViewById(R.id.chat_edittext);
|
||||||
|
sendButton = (ImageButton) findViewById(R.id.chat_send);
|
||||||
|
|
||||||
|
sendButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chatListView = refreshChatListView.getRefreshableView();
|
||||||
|
chatListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
|
||||||
|
chatListView.setStackFromBottom(true);
|
||||||
|
|
||||||
|
String serverName = Util.getServerName(this, Util.getActiveServer(this));
|
||||||
|
String userName = Util.getUserName(this, Util.getActiveServer(this));
|
||||||
|
String title = String.format("%s [%s@%s]", getResources().getString(R.string.button_bar_chat), userName, serverName);
|
||||||
|
|
||||||
|
getActionBar().setSubtitle(title);
|
||||||
|
|
||||||
|
messageEditText.setImeActionLabel("Send", KeyEvent.KEYCODE_ENTER);
|
||||||
|
|
||||||
|
messageEditText.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable editable) {
|
||||||
|
sendButton.setEnabled(!Util.isNullOrWhiteSpace(editable.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
messageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE || (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN)) {
|
||||||
|
sendMessage();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
refreshChatListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
|
||||||
|
@Override
|
||||||
|
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
|
||||||
|
new GetDataTask().execute();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
View chatMenuItem = findViewById(R.id.menu_chat);
|
||||||
|
menuDrawer.setActiveView(chatMenuItem);
|
||||||
|
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage() {
|
||||||
|
final String message = messageEditText.getText().toString();
|
||||||
|
|
||||||
|
if (!Util.isNullOrWhiteSpace(message)) {
|
||||||
|
messageEditText.setText("");
|
||||||
|
|
||||||
|
BackgroundTask<Void> task = new TabActivityBackgroundTask<Void>(ChatActivity.this) {
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground() throws Throwable {
|
||||||
|
MusicService musicService = MusicServiceFactory.getMusicService(ChatActivity.this);
|
||||||
|
musicService.addChatMessage(message, ChatActivity.this, this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done(Void result) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
if (!messageList.isEmpty()) {
|
||||||
|
ChatAdapter chatAdapter = new ChatAdapter(ChatActivity.this, messageList);
|
||||||
|
chatListView.setAdapter(chatAdapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void load() {
|
||||||
|
BackgroundTask<List<ChatMessage>> task = new TabActivityBackgroundTask<List<ChatMessage>>(this) {
|
||||||
|
@Override
|
||||||
|
protected List<ChatMessage> doInBackground() throws Throwable {
|
||||||
|
MusicService musicService = MusicServiceFactory.getMusicService(ChatActivity.this);
|
||||||
|
return musicService.getChatMessages(lastChatMessageTime, ChatActivity.this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done(List<ChatMessage> result) {
|
||||||
|
if (result != null && !result.isEmpty()) {
|
||||||
|
// Reset lastChatMessageTime if we have a newer message
|
||||||
|
for (ChatMessage message : result) {
|
||||||
|
if (message.getTime() > lastChatMessageTime) {
|
||||||
|
lastChatMessageTime = message.getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse results to show them on the bottom
|
||||||
|
Collections.reverse(result);
|
||||||
|
messageList.addAll(result);
|
||||||
|
|
||||||
|
ChatAdapter chatAdapter = new ChatAdapter(ChatActivity.this, messageList);
|
||||||
|
chatListView.setAdapter(chatAdapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refresh() {
|
||||||
|
lastChatMessageTime = (long) 0;
|
||||||
|
messageList = new ArrayList<ChatMessage>();
|
||||||
|
|
||||||
|
finish();
|
||||||
|
Intent intent = getIntent();
|
||||||
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||||
|
Util.startActivityWithoutTransition(this, intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String[] result) {
|
||||||
|
refreshChatListView.onRefreshComplete();
|
||||||
|
super.onPostExecute(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] doInBackground(Void... params) {
|
||||||
|
refresh();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -96,12 +96,6 @@ public final class HelpActivity extends Activity implements OnClickListener {
|
|||||||
View aboutMenuItem = findViewById(R.id.menu_about);
|
View aboutMenuItem = findViewById(R.id.menu_about);
|
||||||
menuDrawer.setActiveView(aboutMenuItem);
|
menuDrawer.setActiveView(aboutMenuItem);
|
||||||
|
|
||||||
TextView activeView = (TextView)findViewById(menuActiveViewId);
|
|
||||||
|
|
||||||
if (activeView != null) {
|
|
||||||
menuDrawer.setActiveView(activeView);
|
|
||||||
}
|
|
||||||
|
|
||||||
webView = (WebView) findViewById(R.id.help_contents);
|
webView = (WebView) findViewById(R.id.help_contents);
|
||||||
webView.getSettings().setJavaScriptEnabled(true);
|
webView.getSettings().setJavaScriptEnabled(true);
|
||||||
webView.setWebViewClient(new HelpClient());
|
webView.setWebViewClient(new HelpClient());
|
||||||
@ -231,6 +225,9 @@ public final class HelpActivity extends Activity implements OnClickListener {
|
|||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
Util.startActivityWithoutTransition(this, intent);
|
Util.startActivityWithoutTransition(this, intent);
|
||||||
break;
|
break;
|
||||||
|
case R.id.menu_chat:
|
||||||
|
Util.startActivityWithoutTransition(this, ChatActivity.class);
|
||||||
|
break;
|
||||||
case R.id.menu_now_playing:
|
case R.id.menu_now_playing:
|
||||||
Util.startActivityWithoutTransition(this, DownloadActivity.class);
|
Util.startActivityWithoutTransition(this, DownloadActivity.class);
|
||||||
break;
|
break;
|
||||||
|
@ -623,6 +623,9 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
|
|||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
Util.startActivityWithoutTransition(this, intent);
|
Util.startActivityWithoutTransition(this, intent);
|
||||||
break;
|
break;
|
||||||
|
case R.id.menu_chat:
|
||||||
|
Util.startActivityWithoutTransition(this, ChatActivity.class);
|
||||||
|
break;
|
||||||
case R.id.menu_now_playing:
|
case R.id.menu_now_playing:
|
||||||
Util.startActivityWithoutTransition(this, DownloadActivity.class);
|
Util.startActivityWithoutTransition(this, DownloadActivity.class);
|
||||||
break;
|
break;
|
||||||
|
@ -49,6 +49,8 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListAdapter;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.R;
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
@ -69,7 +71,6 @@ import com.thejoshwa.ultrasonic.androidapp.util.LoadingTask;
|
|||||||
import com.thejoshwa.ultrasonic.androidapp.util.ModalBackgroundTask;
|
import com.thejoshwa.ultrasonic.androidapp.util.ModalBackgroundTask;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.SilentBackgroundTask;
|
import com.thejoshwa.ultrasonic.androidapp.util.SilentBackgroundTask;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.Util;
|
import com.thejoshwa.ultrasonic.androidapp.util.Util;
|
||||||
|
|
||||||
import net.simonvt.menudrawer.MenuDrawer;
|
import net.simonvt.menudrawer.MenuDrawer;
|
||||||
import net.simonvt.menudrawer.Position;
|
import net.simonvt.menudrawer.Position;
|
||||||
|
|
||||||
@ -124,6 +125,7 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
|
|||||||
findViewById(R.id.menu_browse).setOnClickListener(this);
|
findViewById(R.id.menu_browse).setOnClickListener(this);
|
||||||
searchMenuItem.setOnClickListener(this);
|
searchMenuItem.setOnClickListener(this);
|
||||||
playlistsMenuItem.setOnClickListener(this);
|
playlistsMenuItem.setOnClickListener(this);
|
||||||
|
findViewById(R.id.menu_chat).setOnClickListener(this);
|
||||||
findViewById(R.id.menu_now_playing).setOnClickListener(this);
|
findViewById(R.id.menu_now_playing).setOnClickListener(this);
|
||||||
findViewById(R.id.menu_settings).setOnClickListener(this);
|
findViewById(R.id.menu_settings).setOnClickListener(this);
|
||||||
findViewById(R.id.menu_about).setOnClickListener(this);
|
findViewById(R.id.menu_about).setOnClickListener(this);
|
||||||
@ -492,6 +494,17 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setListAdapterOnListViewOnUiThread(final ListView view, final ListAdapter adapter) {
|
||||||
|
this.runOnUiThread( new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (view != null) {
|
||||||
|
view.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void setOnTouchListenerOnUiThread(final View view, final View.OnTouchListener listener) {
|
public void setOnTouchListenerOnUiThread(final View view, final View.OnTouchListener listener) {
|
||||||
this.runOnUiThread( new Runnable() {
|
this.runOnUiThread( new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -945,6 +958,9 @@ public class SubsonicTabActivity extends Activity implements OnClickListener{
|
|||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
Util.startActivityWithoutTransition(SubsonicTabActivity.this, intent);
|
Util.startActivityWithoutTransition(SubsonicTabActivity.this, intent);
|
||||||
break;
|
break;
|
||||||
|
case R.id.menu_chat:
|
||||||
|
Util.startActivityWithoutTransition(SubsonicTabActivity.this, ChatActivity.class);
|
||||||
|
break;
|
||||||
case R.id.menu_now_playing:
|
case R.id.menu_now_playing:
|
||||||
Util.startActivityWithoutTransition(SubsonicTabActivity.this, DownloadActivity.class);
|
Util.startActivityWithoutTransition(SubsonicTabActivity.this, DownloadActivity.class);
|
||||||
break;
|
break;
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ChatMessage implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 496544310289324167L;
|
||||||
|
private String username;
|
||||||
|
private Long time;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(Long time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
124
src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java
Normal file
124
src/com/thejoshwa/ultrasonic/androidapp/domain/Share.java
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
|
||||||
|
|
||||||
|
public class Share implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1487561657691009668L;
|
||||||
|
private String id;
|
||||||
|
private String url;
|
||||||
|
private String description;
|
||||||
|
private String username;
|
||||||
|
private Date created;
|
||||||
|
private Date lastVisited;
|
||||||
|
private Date expires;
|
||||||
|
private Long visitCount;
|
||||||
|
private List<Entry> entries;
|
||||||
|
|
||||||
|
public Share() {
|
||||||
|
entries = new ArrayList<Entry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreated(String created) {
|
||||||
|
if (created != null) {
|
||||||
|
try {
|
||||||
|
this.created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(created);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
this.created = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.created = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastVisited() {
|
||||||
|
return lastVisited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastVisited(String lastVisited) {
|
||||||
|
if (lastVisited != null) {
|
||||||
|
try {
|
||||||
|
this.lastVisited = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(lastVisited);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
this.lastVisited = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.lastVisited = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getExpires() {
|
||||||
|
return expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpires(String expires) {
|
||||||
|
if (expires != null) {
|
||||||
|
try {
|
||||||
|
this.expires = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(expires);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
this.expires = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.expires = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getVisitCount() {
|
||||||
|
return visitCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisitCount(Long visitCount) {
|
||||||
|
this.visitCount = visitCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Entry> getEntries() {
|
||||||
|
return this.entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntry(Entry entry) {
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
@ -26,15 +26,18 @@ import org.apache.http.HttpResponse;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Lyrics;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Lyrics;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.MusicFolder;
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicFolder;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.Share;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
|
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.LRUCache;
|
import com.thejoshwa.ultrasonic.androidapp.util.LRUCache;
|
||||||
@ -341,10 +344,12 @@ public class CachedMusicService implements MusicService {
|
|||||||
public List<Genre> getGenres(Context context, ProgressListener progressListener) throws Exception {
|
public List<Genre> getGenres(Context context, ProgressListener progressListener) throws Exception {
|
||||||
checkSettingsChanged(context);
|
checkSettingsChanged(context);
|
||||||
List<Genre> result = cachedGenres.get();
|
List<Genre> result = cachedGenres.get();
|
||||||
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = musicService.getGenres(context, progressListener);
|
result = musicService.getGenres(context, progressListener);
|
||||||
cachedGenres.set(result);
|
cachedGenres.set(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,4 +357,19 @@ public class CachedMusicService implements MusicService {
|
|||||||
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception {
|
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception {
|
||||||
return musicService.getSongsByGenre(genre, count, offset, context, progressListener);
|
return musicService.getSongsByGenre(genre, count, offset, context, progressListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Share> getShares(Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
return musicService.getShares(context, progressListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
return musicService.getChatMessages(since, context, progressListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
musicService.addChatMessage(message, context, progressListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import org.apache.http.HttpResponse;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
||||||
@ -35,6 +36,7 @@ import com.thejoshwa.ultrasonic.androidapp.domain.MusicFolder;
|
|||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.Share;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
|
import com.thejoshwa.ultrasonic.androidapp.util.CancellableTask;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener;
|
import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener;
|
||||||
@ -121,4 +123,10 @@ public interface MusicService {
|
|||||||
JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
|
JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
|
JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
|
List<Share> getShares(Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
|
List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
|
void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception;
|
||||||
}
|
}
|
@ -70,18 +70,22 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.R;
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Genre;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Indexes;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
import com.thejoshwa.ultrasonic.androidapp.domain.JukeboxStatus;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Lyrics;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Lyrics;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.MusicFolder;
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicFolder;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Playlist;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchCritera;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
import com.thejoshwa.ultrasonic.androidapp.domain.SearchResult;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.ServerInfo;
|
import com.thejoshwa.ultrasonic.androidapp.domain.ServerInfo;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.Share;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
import com.thejoshwa.ultrasonic.androidapp.domain.Version;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.AlbumListParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.AlbumListParser;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.ChatMessageParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.ErrorParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.ErrorParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.GenreParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.GenreParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.IndexesParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.IndexesParser;
|
||||||
@ -95,6 +99,7 @@ import com.thejoshwa.ultrasonic.androidapp.service.parser.PlaylistsParser;
|
|||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.RandomSongsParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.RandomSongsParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.SearchResult2Parser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.SearchResult2Parser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.SearchResultParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.SearchResultParser;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.ShareParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.parser.VersionParser;
|
import com.thejoshwa.ultrasonic.androidapp.service.parser.VersionParser;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.ssl.SSLSocketFactory;
|
import com.thejoshwa.ultrasonic.androidapp.service.ssl.SSLSocketFactory;
|
||||||
import com.thejoshwa.ultrasonic.androidapp.service.ssl.TrustSelfSignedStrategy;
|
import com.thejoshwa.ultrasonic.androidapp.service.ssl.TrustSelfSignedStrategy;
|
||||||
@ -1143,4 +1148,61 @@ public class RESTMusicService implements MusicService {
|
|||||||
Util.close(reader);
|
Util.close(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Share> getShares(Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
checkServerVersion(context, "1.6", "Shares not supported.");
|
||||||
|
|
||||||
|
Reader reader = getReader(context, progressListener, "getShares", null);
|
||||||
|
try {
|
||||||
|
return new ShareParser(context).parse(reader, progressListener);
|
||||||
|
} finally {
|
||||||
|
Util.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
checkServerVersion(context, "1.2", "Chat not supported.");
|
||||||
|
|
||||||
|
HttpParams params = new BasicHttpParams();
|
||||||
|
HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS);
|
||||||
|
|
||||||
|
List<String> parameterNames = new ArrayList<String>();
|
||||||
|
List<Object> parameterValues = new ArrayList<Object>();
|
||||||
|
|
||||||
|
parameterNames.add("since");
|
||||||
|
parameterValues.add(since);
|
||||||
|
|
||||||
|
Reader reader = getReader(context, progressListener, "getChatMessages", params, parameterNames, parameterValues);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new ChatMessageParser(context).parse(reader, progressListener);
|
||||||
|
} finally {
|
||||||
|
Util.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception {
|
||||||
|
checkServerVersion(context, "1.2", "Chat not supported.");
|
||||||
|
|
||||||
|
HttpParams params = new BasicHttpParams();
|
||||||
|
HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS);
|
||||||
|
|
||||||
|
List<String> parameterNames = new ArrayList<String>();
|
||||||
|
List<Object> parameterValues = new ArrayList<Object>();
|
||||||
|
|
||||||
|
parameterNames.add("message");
|
||||||
|
parameterValues.add(message);
|
||||||
|
|
||||||
|
Reader reader = getReader(context, progressListener, "addChatMessage", params, parameterNames, parameterValues);
|
||||||
|
|
||||||
|
try {
|
||||||
|
new ErrorParser(context).parse(reader);
|
||||||
|
} finally {
|
||||||
|
Util.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.service.parser;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Joshua Bahnsen
|
||||||
|
*/
|
||||||
|
public class ChatMessageParser extends AbstractParser {
|
||||||
|
|
||||||
|
public ChatMessageParser(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ChatMessage> parse(Reader reader, ProgressListener progressListener) throws Exception {
|
||||||
|
updateProgress(progressListener, R.string.parser_reading);
|
||||||
|
init(reader);
|
||||||
|
List<ChatMessage> result = new ArrayList<ChatMessage>();
|
||||||
|
int eventType;
|
||||||
|
|
||||||
|
do {
|
||||||
|
eventType = nextParseEvent();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
String name = getElementName();
|
||||||
|
if ("chatMessage".equals(name)) {
|
||||||
|
ChatMessage chatMessage = new ChatMessage();
|
||||||
|
chatMessage.setUsername(get("username"));
|
||||||
|
chatMessage.setTime(getLong("time"));
|
||||||
|
chatMessage.setMessage(get("message"));
|
||||||
|
result.add(chatMessage);
|
||||||
|
} else if ("error".equals(name)) {
|
||||||
|
handleError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
|
|
||||||
|
validate();
|
||||||
|
updateProgress(progressListener, R.string.parser_reading_done);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.service.parser;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.Share;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.ProgressListener;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Joshua Bahnsen
|
||||||
|
*/
|
||||||
|
public class ShareParser extends MusicDirectoryEntryParser {
|
||||||
|
|
||||||
|
public ShareParser(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Share> parse(Reader reader, ProgressListener progressListener) throws Exception {
|
||||||
|
|
||||||
|
updateProgress(progressListener, R.string.parser_reading);
|
||||||
|
init(reader);
|
||||||
|
|
||||||
|
List<Share> dir = new ArrayList<Share>();
|
||||||
|
Share share = null;
|
||||||
|
int eventType;
|
||||||
|
|
||||||
|
do {
|
||||||
|
eventType = nextParseEvent();
|
||||||
|
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
String name = getElementName();
|
||||||
|
|
||||||
|
if ("share".equals(name)) {
|
||||||
|
share = new Share();
|
||||||
|
share.setCreated(get("created"));
|
||||||
|
share.setDescription(get("description"));
|
||||||
|
share.setExpires(get("expires"));
|
||||||
|
share.setId(get("id"));
|
||||||
|
share.setLastVisited(get("lastVisited"));
|
||||||
|
share.setUrl(get("url"));
|
||||||
|
share.setUsername(get("username"));
|
||||||
|
share.setVisitCount(getLong("visitCount"));
|
||||||
|
} else if ("entry".equals(name)) {
|
||||||
|
share.addEntry(parseEntry(null, false));
|
||||||
|
} else if ("error".equals(name)) {
|
||||||
|
handleError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
|
|
||||||
|
validate();
|
||||||
|
updateProgress(progressListener, R.string.parser_reading_done);
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
}
|
@ -203,6 +203,14 @@ public class Util extends DownloadActivity {
|
|||||||
return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null);
|
return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getUserName(Context context, int instance) {
|
||||||
|
if (instance == 0) {
|
||||||
|
return context.getResources().getString(R.string.main_offline);
|
||||||
|
}
|
||||||
|
SharedPreferences prefs = getPreferences(context);
|
||||||
|
return prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean getServerEnabled(Context context, int instance) {
|
public static boolean getServerEnabled(Context context, int instance) {
|
||||||
if (instance == 0) {
|
if (instance == 0) {
|
||||||
return true;
|
return true;
|
||||||
@ -1226,4 +1234,8 @@ public class Util extends DownloadActivity {
|
|||||||
SharedPreferences prefs = getPreferences(context);
|
SharedPreferences prefs = getPreferences(context);
|
||||||
return prefs.getBoolean(Constants.PREFERENCES_KEY_ID3_TAGS, false);
|
return prefs.getBoolean(Constants.PREFERENCES_KEY_ID3_TAGS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isNullOrWhiteSpace(String string) {
|
||||||
|
return string == null || string.isEmpty() || string.trim().isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
101
src/com/thejoshwa/ultrasonic/androidapp/view/ChatAdapter.java
Normal file
101
src/com/thejoshwa/ultrasonic/androidapp/view/ChatAdapter.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package com.thejoshwa.ultrasonic.androidapp.view;
|
||||||
|
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.activity.SubsonicTabActivity;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.domain.ChatMessage;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.util.Util;
|
||||||
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||||||
|
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.util.Linkify;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ChatAdapter extends ArrayAdapter<ChatMessage> {
|
||||||
|
|
||||||
|
private final SubsonicTabActivity activity;
|
||||||
|
private ArrayList<ChatMessage> messages;
|
||||||
|
|
||||||
|
private static final String phoneRegex = "1?\\W*([2-9][0-8][0-9])\\W*([2-9][0-9]{2})\\W*([0-9]{4})"; //you can just place your support phone here
|
||||||
|
private static final Pattern phoneMatcher = Pattern.compile(phoneRegex);
|
||||||
|
|
||||||
|
public ChatAdapter(SubsonicTabActivity activity, ArrayList<ChatMessage> messages) {
|
||||||
|
super(activity, R.layout.chat_item, messages);
|
||||||
|
this.activity = activity;
|
||||||
|
this.messages = messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return messages.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ChatMessage message = this.getItem(position);
|
||||||
|
|
||||||
|
ViewHolder holder;
|
||||||
|
int layout;
|
||||||
|
|
||||||
|
String messageUser = message.getUsername();
|
||||||
|
Date messageTime = new java.util.Date(message.getTime());
|
||||||
|
String messageText = message.getMessage();
|
||||||
|
|
||||||
|
String me = Util.getUserName(activity, Util.getActiveServer(activity));
|
||||||
|
|
||||||
|
if (messageUser.equals(me)) {
|
||||||
|
layout = R.layout.chat_item_reverse;
|
||||||
|
} else {
|
||||||
|
layout = R.layout.chat_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (convertView == null)
|
||||||
|
{
|
||||||
|
holder = new ViewHolder();
|
||||||
|
|
||||||
|
convertView = LayoutInflater.from(activity).inflate(layout, parent, false);
|
||||||
|
|
||||||
|
TextView usernameView = (TextView) convertView.findViewById(R.id.chat_username);
|
||||||
|
TextView timeView = (TextView) convertView.findViewById(R.id.chat_time);
|
||||||
|
TextView messageView = (TextView) convertView.findViewById(R.id.chat_message);
|
||||||
|
|
||||||
|
messageView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
Linkify.addLinks(messageView, Linkify.EMAIL_ADDRESSES);
|
||||||
|
Linkify.addLinks(messageView, Linkify.WEB_URLS);
|
||||||
|
Linkify.addLinks(messageView, phoneMatcher, "tel:");
|
||||||
|
|
||||||
|
holder.message = messageView;
|
||||||
|
holder.username = usernameView;
|
||||||
|
holder.time = timeView;
|
||||||
|
|
||||||
|
convertView.setTag(holder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
holder = (ViewHolder) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(activity);
|
||||||
|
String messageTimeFormatted = String.format("[%s]", timeFormat.format(messageTime));
|
||||||
|
|
||||||
|
holder.username.setText(messageUser);
|
||||||
|
holder.message.setText(messageText);
|
||||||
|
holder.time.setText(messageTimeFormatted);
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ViewHolder
|
||||||
|
{
|
||||||
|
TextView message;
|
||||||
|
TextView username;
|
||||||
|
TextView time;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user