From 167d895345e7482807d65efe01745cb123846eda Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Wed, 22 May 2013 22:37:55 -0700 Subject: Merge Chat Tab from UltraSonic --- .../daneren2005/dsub/activity/MainActivity.java | 6 +- .../daneren2005/dsub/domain/ChatMessage.java | 51 +++++++ .../src/github/daneren2005/dsub/domain/Share.java | 140 +++++++++++++++++ .../daneren2005/dsub/fragments/ChatFragment.java | 167 +++++++++++++++++++++ .../dsub/service/CachedMusicService.java | 18 ++- .../daneren2005/dsub/service/MusicService.java | 8 + .../daneren2005/dsub/service/RESTMusicService.java | 58 +++++++ .../dsub/service/parser/ChatMessageParser.java | 67 +++++++++ .../dsub/service/parser/ShareParser.java | 77 ++++++++++ .../src/github/daneren2005/dsub/util/Util.java | 12 ++ .../github/daneren2005/dsub/view/ChatAdapter.java | 100 ++++++++++++ 11 files changed, 699 insertions(+), 5 deletions(-) create mode 100644 subsonic-android/src/github/daneren2005/dsub/domain/ChatMessage.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/domain/Share.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/fragments/ChatFragment.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/service/parser/ChatMessageParser.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/service/parser/ShareParser.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/view/ChatAdapter.java (limited to 'subsonic-android/src/github/daneren2005') diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java index d0eb86ef..16036bf1 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java @@ -1,9 +1,6 @@ package github.daneren2005.dsub.activity; import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.TypedArray; @@ -15,13 +12,13 @@ import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.view.Menu; import android.support.v4.view.ViewPager; import android.util.Log; -import android.view.KeyEvent; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.PlayerState; +import github.daneren2005.dsub.fragments.ChatFragment; import github.daneren2005.dsub.fragments.MainFragment; import github.daneren2005.dsub.fragments.SelectArtistFragment; import github.daneren2005.dsub.fragments.SelectPlaylistFragment; @@ -155,6 +152,7 @@ public class MainActivity extends SubsonicActivity { addTab("Home", MainFragment.class, null); addTab("Library", SelectArtistFragment.class, null); addTab("Playlists", SelectPlaylistFragment.class, null); + addTab("Chat", ChatFragment.class, null); getSupportActionBar().setDisplayHomeAsUpEnabled(false); getSupportActionBar().setHomeButtonEnabled(false); diff --git a/subsonic-android/src/github/daneren2005/dsub/domain/ChatMessage.java b/subsonic-android/src/github/daneren2005/dsub/domain/ChatMessage.java new file mode 100644 index 00000000..471594e9 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/domain/ChatMessage.java @@ -0,0 +1,51 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + + Copyright 2009 (C) Sindre Mehus + */ +package github.daneren2005.dsub.domain; + +import java.io.Serializable; + +public class ChatMessage implements Serializable { + 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; + } +} diff --git a/subsonic-android/src/github/daneren2005/dsub/domain/Share.java b/subsonic-android/src/github/daneren2005/dsub/domain/Share.java new file mode 100644 index 00000000..d19496f9 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/domain/Share.java @@ -0,0 +1,140 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + + Copyright 2009 (C) Sindre Mehus + */ +package github.daneren2005.dsub.domain; + +import github.daneren2005.dsub.domain.MusicDirectory.Entry; +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; + +public class Share implements Serializable { + 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 entries; + + public Share() { + entries = new ArrayList(); + } + + 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 getEntries() { + return this.entries; + } + + public void addEntry(Entry entry) { + entries.add(entry); + } + } diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/ChatFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/ChatFragment.java new file mode 100644 index 00000000..8fba2526 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/fragments/ChatFragment.java @@ -0,0 +1,167 @@ +package github.daneren2005.dsub.fragments; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ListView; +import android.widget.TextView; +import github.daneren2005.dsub.R; +import github.daneren2005.dsub.domain.ChatMessage; +import github.daneren2005.dsub.service.MusicService; +import github.daneren2005.dsub.service.MusicServiceFactory; +import github.daneren2005.dsub.util.BackgroundTask; +import github.daneren2005.dsub.util.TabBackgroundTask; +import github.daneren2005.dsub.util.Util; +import github.daneren2005.dsub.view.ChatAdapter; +import com.actionbarsherlock.view.Menu; + +/** + * @author Joshua Bahnsen + */ +public class ChatFragment extends SubsonicFragment { + private ListView chatListView; + private EditText messageEditText; + private ImageButton sendButton; + private Long lastChatMessageTime = (long) 0; + private ArrayList messageList = new ArrayList(); + + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + rootView = inflater.inflate(R.layout.chat, container, false); + + messageEditText = (EditText) rootView.findViewById(R.id.chat_edittext); + sendButton = (ImageButton) rootView.findViewById(R.id.chat_send); + + sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + sendMessage(); + } + }); + + chatListView = (ListView) rootView.findViewById(R.id.chat_entries); + + 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; + } + }); + + invalidated = true; + return rootView; + } + + @Override + public void onCreateOptionsMenu(Menu menu, com.actionbarsherlock.view.MenuInflater menuInflater) { + menuInflater.inflate(R.menu.empty, menu); + } + + @Override + public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { + if(super.onOptionsItemSelected(item)) { + return true; + } + + return false; + } + + @Override + protected void refresh(boolean refresh) { + load(); + } + + private synchronized void load() { + setTitle(R.string.button_bar_chat); + BackgroundTask> task = new TabBackgroundTask>(this) { + @Override + protected List doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + return musicService.getChatMessages(lastChatMessageTime, context, this); + } + + @Override + protected void done(List 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(context, messageList); + chatListView.setAdapter(chatAdapter); + } + } + }; + + task.execute(); + } + + private void sendMessage() { + final String message = messageEditText.getText().toString(); + + if (!Util.isNullOrWhiteSpace(message)) { + messageEditText.setText(""); + + BackgroundTask task = new TabBackgroundTask(this) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.addChatMessage(message, context, this); + return null; + } + + @Override + protected void done(Void result) { + load(); + } + }; + + task.execute(); + } + } +} \ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java index 32807289..3eb4184f 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -25,15 +25,16 @@ import org.apache.http.HttpResponse; import android.content.Context; import android.graphics.Bitmap; +import github.daneren2005.dsub.domain.ChatMessage; import github.daneren2005.dsub.domain.Indexes; import github.daneren2005.dsub.domain.JukeboxStatus; import github.daneren2005.dsub.domain.Lyrics; import github.daneren2005.dsub.domain.MusicDirectory; -import github.daneren2005.dsub.domain.MusicDirectory.Entry; import github.daneren2005.dsub.domain.MusicFolder; import github.daneren2005.dsub.domain.Playlist; import github.daneren2005.dsub.domain.SearchCritera; import github.daneren2005.dsub.domain.SearchResult; +import github.daneren2005.dsub.domain.Share; import github.daneren2005.dsub.domain.Version; import github.daneren2005.dsub.util.CancellableTask; import github.daneren2005.dsub.util.LRUCache; @@ -259,6 +260,21 @@ public class CachedMusicService implements MusicService { public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception { musicService.setStarred(id, starred, context, progressListener); } + + @Override + public List getShares(Context context, ProgressListener progressListener) throws Exception { + return musicService.getShares(context, progressListener); + } + + @Override + public List 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); + } private void checkSettingsChanged(Context context) { String newUrl = Util.getRestUrl(context, null); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java index de3046d7..88391e53 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java @@ -24,6 +24,7 @@ import org.apache.http.HttpResponse; import android.content.Context; import android.graphics.Bitmap; +import github.daneren2005.dsub.domain.ChatMessage; import github.daneren2005.dsub.domain.Indexes; import github.daneren2005.dsub.domain.JukeboxStatus; import github.daneren2005.dsub.domain.Lyrics; @@ -32,6 +33,7 @@ import github.daneren2005.dsub.domain.MusicFolder; import github.daneren2005.dsub.domain.Playlist; import github.daneren2005.dsub.domain.SearchCritera; import github.daneren2005.dsub.domain.SearchResult; +import github.daneren2005.dsub.domain.Share; import github.daneren2005.dsub.domain.Version; import github.daneren2005.dsub.util.CancellableTask; import github.daneren2005.dsub.util.ProgressListener; @@ -102,4 +104,10 @@ public interface MusicService { JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception; void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception; + + List getShares(Context context, ProgressListener progressListener) throws Exception; + + List getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception; + + void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception; } \ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java index 24dcbabd..daa9291a 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -73,6 +73,7 @@ import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.*; import github.daneren2005.dsub.domain.MusicDirectory.Entry; import github.daneren2005.dsub.service.parser.AlbumListParser; +import github.daneren2005.dsub.service.parser.ChatMessageParser; import github.daneren2005.dsub.service.parser.ErrorParser; import github.daneren2005.dsub.service.parser.IndexesParser; import github.daneren2005.dsub.service.parser.JukeboxStatusParser; @@ -85,6 +86,7 @@ import github.daneren2005.dsub.service.parser.PlaylistsParser; import github.daneren2005.dsub.service.parser.RandomSongsParser; import github.daneren2005.dsub.service.parser.SearchResult2Parser; import github.daneren2005.dsub.service.parser.SearchResultParser; +import github.daneren2005.dsub.service.parser.ShareParser; import github.daneren2005.dsub.service.parser.StarredListParser; import github.daneren2005.dsub.service.parser.VersionParser; import github.daneren2005.dsub.service.ssl.SSLSocketFactory; @@ -729,6 +731,62 @@ public class RESTMusicService implements MusicService { Util.close(reader); } } + + @Override + public List 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 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 parameterNames = new ArrayList(); + List parameterValues = new ArrayList(); + + 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 parameterNames = new ArrayList(); + List parameterValues = new ArrayList(); + + 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); + } + } private Reader getReader(Context context, ProgressListener progressListener, String method, HttpParams requestParams) throws Exception { return getReader(context, progressListener, method, requestParams, Collections.emptyList(), Collections.emptyList()); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/ChatMessageParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/ChatMessageParser.java new file mode 100644 index 00000000..1425a734 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/ChatMessageParser.java @@ -0,0 +1,67 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + + Copyright 2009 (C) Sindre Mehus + */ +package github.daneren2005.dsub.service.parser; + +import android.content.Context; +import github.daneren2005.dsub.R; +import github.daneren2005.dsub.domain.ChatMessage; +import github.daneren2005.dsub.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 parse(Reader reader, ProgressListener progressListener) throws Exception { + updateProgress(progressListener, R.string.parser_reading); + init(reader); + List result = new ArrayList(); + 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; + } +} diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/ShareParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/ShareParser.java new file mode 100644 index 00000000..c317e799 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/ShareParser.java @@ -0,0 +1,77 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + + Copyright 2009 (C) Sindre Mehus + */ +package github.daneren2005.dsub.service.parser; + +import android.content.Context; +import github.daneren2005.dsub.R; +import github.daneren2005.dsub.domain.Share; +import github.daneren2005.dsub.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 parse(Reader reader, ProgressListener progressListener) throws Exception { + + updateProgress(progressListener, R.string.parser_reading); + init(reader); + + List dir = new ArrayList(); + 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)); + } else if ("error".equals(name)) { + handleError(); + } + } + } while (eventType != XmlPullParser.END_DOCUMENT); + + validate(); + updateProgress(progressListener, R.string.parser_reading_done); + + return dir; + } +} \ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Util.java b/subsonic-android/src/github/daneren2005/dsub/util/Util.java index a7c1b720..93acfcb8 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Util.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Util.java @@ -209,6 +209,14 @@ public final class Util { SharedPreferences prefs = getPreferences(context); 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 void setServerRestVersion(Context context, Version version) { SERVER_REST_VERSIONS.put(getActiveServer(context), version); @@ -634,6 +642,10 @@ public final class Util { throw new RuntimeException(x.getMessage(), x); } } + + public static boolean isNullOrWhiteSpace(String string) { + return string == null || string.isEmpty() || string.trim().isEmpty(); + } public static boolean isNetworkConnected(Context context) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); diff --git a/subsonic-android/src/github/daneren2005/dsub/view/ChatAdapter.java b/subsonic-android/src/github/daneren2005/dsub/view/ChatAdapter.java new file mode 100644 index 00000000..518f81ef --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/view/ChatAdapter.java @@ -0,0 +1,100 @@ +package github.daneren2005.dsub.view; + +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 github.daneren2005.dsub.R; +import github.daneren2005.dsub.activity.SubsonicActivity; +import github.daneren2005.dsub.domain.ChatMessage; +import github.daneren2005.dsub.util.Util; + +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.regex.Pattern; + +public class ChatAdapter extends ArrayAdapter { + + private final SubsonicActivity activity; + private ArrayList 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(SubsonicActivity activity, ArrayList 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; + } +} -- cgit v1.2.3