From 2c78483c64826d0977fd40d292a01f3d9f1f6ed1 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Sat, 21 Mar 2015 12:08:37 +0100 Subject: [PATCH] Refactoring ServersActivity to new (more "Material") OverviewFragment. The new launch activity is MainActivity. The other activities will mostly become fragments. --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 5 +- .../java/org/yaaic/activity/MainActivity.java | 101 +++++ .../org/yaaic/activity/ServersActivity.java | 347 ------------------ .../org/yaaic/adapter/ServerListAdapter.java | 153 -------- .../org/yaaic/adapter/ServersAdapter.java | 128 +++++++ .../org/yaaic/fragment/OverviewFragment.java | 183 +++++++++ .../java/org/yaaic/menu/ServerPopupMenu.java | 79 ++++ app/src/main/java/org/yaaic/model/Extra.java | 3 + app/src/main/java/org/yaaic/model/Server.java | 20 - .../main/res/drawable-hdpi/ic_action_menu.png | Bin 0 -> 294 bytes app/src/main/res/drawable-mdpi/connected.png | Bin 454 -> 0 bytes app/src/main/res/drawable-mdpi/connecting.png | Bin 498 -> 0 bytes .../main/res/drawable-mdpi/disconnected.png | Bin 440 -> 0 bytes .../main/res/drawable-mdpi/ic_action_menu.png | Bin 0 -> 176 bytes .../res/drawable-xhdpi/ic_action_menu.png | Bin 0 -> 394 bytes .../res/drawable-xxhdpi/ic_action_menu.png | Bin 0 -> 715 bytes app/src/main/res/layout/activity_main.xml | 10 + app/src/main/res/layout/addserveritem.xml | 30 -- app/src/main/res/layout/fragment_servers.xml | 40 ++ app/src/main/res/layout/item_server.xml | 70 ++++ app/src/main/res/layout/serveritem.xml | 51 --- app/src/main/res/layout/servers.xml | 4 +- app/src/main/res/menu/context_server.xml | 15 + app/src/main/res/menu/servers.xml | 35 -- app/src/main/res/values/colors.xml | 4 + 26 files changed, 639 insertions(+), 641 deletions(-) create mode 100644 app/src/main/java/org/yaaic/activity/MainActivity.java delete mode 100644 app/src/main/java/org/yaaic/activity/ServersActivity.java delete mode 100644 app/src/main/java/org/yaaic/adapter/ServerListAdapter.java create mode 100644 app/src/main/java/org/yaaic/adapter/ServersAdapter.java create mode 100644 app/src/main/java/org/yaaic/fragment/OverviewFragment.java create mode 100644 app/src/main/java/org/yaaic/menu/ServerPopupMenu.java create mode 100755 app/src/main/res/drawable-hdpi/ic_action_menu.png delete mode 100644 app/src/main/res/drawable-mdpi/connected.png delete mode 100644 app/src/main/res/drawable-mdpi/connecting.png delete mode 100644 app/src/main/res/drawable-mdpi/disconnected.png create mode 100755 app/src/main/res/drawable-mdpi/ic_action_menu.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_action_menu.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_menu.png create mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/layout/addserveritem.xml create mode 100644 app/src/main/res/layout/fragment_servers.xml create mode 100644 app/src/main/res/layout/item_server.xml delete mode 100644 app/src/main/res/layout/serveritem.xml create mode 100644 app/src/main/res/menu/context_server.xml delete mode 100644 app/src/main/res/menu/servers.xml diff --git a/app/build.gradle b/app/build.gradle index 27021fc..478dfa2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,6 +22,8 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:22.0.0' + compile 'com.android.support:cardview-v7:22.0.0' + compile "com.android.support:recyclerview-v7:22.0.0" compile 'com.viewpagerindicator:library:2.4.1@aar' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4087fca..95cb7ed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,12 +27,11 @@ along with Yaaic. If not, see . - diff --git a/app/src/main/java/org/yaaic/activity/MainActivity.java b/app/src/main/java/org/yaaic/activity/MainActivity.java new file mode 100644 index 0000000..7e9ff91 --- /dev/null +++ b/app/src/main/java/org/yaaic/activity/MainActivity.java @@ -0,0 +1,101 @@ +/* +Yaaic - Yet Another Android IRC Client + +Copyright 2009-2015 Sebastian Kaspari + +This file is part of Yaaic. + +Yaaic 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. + +Yaaic 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 Yaaic. If not, see . + */ +package org.yaaic.activity; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; + +import org.yaaic.R; +import org.yaaic.fragment.OverviewFragment; +import org.yaaic.irc.IRCBinder; +import org.yaaic.irc.IRCService; +import org.yaaic.model.Extra; +import org.yaaic.model.Server; +import org.yaaic.model.Status; + +/** + * The main activity of Yaaic. We'll add, remove and replace fragments here. + */ +public class MainActivity extends Activity implements OverviewFragment.Callback, ServiceConnection { + private IRCBinder binder; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_main); + } + + @Override + protected void onResume() { + super.onResume(); + + Intent intent = new Intent(this, IRCService.class); + intent.setAction(IRCService.ACTION_BACKGROUND); + startService(intent); + + bindService(intent, this, 0); + } + + @Override + protected void onPause() { + super.onPause(); + + if (binder != null && binder.getService() != null) { + binder.getService().checkServiceStatus(); + } + + unbindService(this); + } + + @Override + public void onServerSelected(Server server) { + Intent intent = new Intent(this, ConversationActivity.class); + + if (server.getStatus() == Status.DISCONNECTED && !server.mayReconnect()) { + server.setStatus(Status.PRE_CONNECTING); + intent.putExtra(Extra.CONNECT, true); + } + + intent.putExtra(Extra.SERVER_ID, server.getId()); + startActivity(intent); + + } + + @Override + public IRCBinder getBinder() { + return binder; + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + binder = (IRCBinder) service; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + binder = null; + } +} diff --git a/app/src/main/java/org/yaaic/activity/ServersActivity.java b/app/src/main/java/org/yaaic/activity/ServersActivity.java deleted file mode 100644 index 434d9b7..0000000 --- a/app/src/main/java/org/yaaic/activity/ServersActivity.java +++ /dev/null @@ -1,347 +0,0 @@ -/* -Yaaic - Yet Another Android IRC Client - -Copyright 2009-2013 Sebastian Kaspari - -This file is part of Yaaic. - -Yaaic 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. - -Yaaic 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 Yaaic. If not, see . - */ -package org.yaaic.activity; - -import java.util.ArrayList; - -import org.yaaic.R; -import org.yaaic.Yaaic; -import org.yaaic.adapter.ServerListAdapter; -import org.yaaic.db.Database; -import org.yaaic.irc.IRCBinder; -import org.yaaic.irc.IRCService; -import org.yaaic.listener.ServerListener; -import org.yaaic.model.Broadcast; -import org.yaaic.model.Extra; -import org.yaaic.model.Server; -import org.yaaic.model.Status; -import org.yaaic.receiver.ServerReceiver; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.IBinder; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ListView; -import android.widget.Toast; - -/** - * List of servers - * - * @author Sebastian Kaspari - */ -public class ServersActivity extends Activity implements ServiceConnection, ServerListener, OnItemClickListener, OnItemLongClickListener { - private IRCBinder binder; - private ServerReceiver receiver; - private ServerListAdapter adapter; - private ListView list; - private static int instanceCount = 0; - - /** - * On create - */ - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - /* - * With activity:launchMode = standard, we get duplicated activities - * depending on the task the app was started in. In order to avoid - * stacking up of this duplicated activities we keep a count of this - * root activity and let it finish if it already exists - * - * Launching the app via the notification icon creates a new task, - * and there doesn't seem to be a way around this so this is needed - */ - if (instanceCount > 0) { - finish(); - } - instanceCount++; - setContentView(R.layout.servers); - - adapter = new ServerListAdapter(); - - list = (ListView) findViewById(android.R.id.list); - list.setAdapter(adapter); - list.setOnItemClickListener(this); - list.setOnItemLongClickListener(this); - } - - /** - * On Destroy - */ - @Override - public void onDestroy() - { - super.onDestroy(); - instanceCount--; - } - - /** - * On resume - */ - @Override - public void onResume() - { - super.onResume(); - - // Start and connect to service - Intent intent = new Intent(this, IRCService.class); - intent.setAction(IRCService.ACTION_BACKGROUND); - startService(intent); - bindService(intent, this, 0); - - receiver = new ServerReceiver(this); - registerReceiver(receiver, new IntentFilter(Broadcast.SERVER_UPDATE)); - - adapter.loadServers(); - } - - /** - * On pause - */ - @Override - public void onPause() - { - super.onPause(); - - if (binder != null && binder.getService() != null) { - binder.getService().checkServiceStatus(); - } - - unbindService(this); - unregisterReceiver(receiver); - } - - /** - * Service connected to Activity - */ - @Override - public void onServiceConnected(ComponentName name, IBinder service) - { - binder = (IRCBinder) service; - } - - /** - * Service disconnected from Activity - */ - @Override - public void onServiceDisconnected(ComponentName name) - { - binder = null; - } - - /** - * On server selected - */ - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - Server server = adapter.getItem(position); - - if (server == null) { - // "Add server" was selected - startActivityForResult(new Intent(this, AddServerActivity.class), 0); - return; - } - - Intent intent = new Intent(this, ConversationActivity.class); - - if (server.getStatus() == Status.DISCONNECTED && !server.mayReconnect()) { - server.setStatus(Status.PRE_CONNECTING); - intent.putExtra("connect", true); - } - - intent.putExtra("serverId", server.getId()); - startActivity(intent); - } - - /** - * On long click - */ - @Override - public boolean onItemLongClick(AdapterView l, View v, int position, long id) - { - final Server server = adapter.getItem(position); - - if (server == null) { - // "Add server" view selected - return true; - } - - final CharSequence[] items = { - getString(R.string.connect), - getString(R.string.disconnect), - getString(R.string.edit), - getString(R.string.delete) - }; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(server.getTitle()); - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int item) { - switch (item) { - case 0: // Connect - if (server.getStatus() == Status.DISCONNECTED) { - binder.connect(server); - server.setStatus(Status.CONNECTING); - adapter.notifyDataSetChanged(); - } - break; - case 1: // Disconnect - server.clearConversations(); - server.setStatus(Status.DISCONNECTED); - server.setMayReconnect(false); - binder.getService().getConnection(server.getId()).quitServer(); - break; - case 2: // Edit - editServer(server.getId()); - break; - case 3: // Delete - binder.getService().getConnection(server.getId()).quitServer(); - deleteServer(server.getId()); - break; - } - } - }); - AlertDialog alert = builder.create(); - alert.show(); - return true; - } - - /** - * Start activity to edit server with given id - * - * @param serverId The id of the server - */ - private void editServer(int serverId) - { - Server server = Yaaic.getInstance().getServerById(serverId); - - if (server.getStatus() != Status.DISCONNECTED) { - Toast.makeText(this, getResources().getString(R.string.disconnect_before_editing), Toast.LENGTH_SHORT).show(); - } - else { - Intent intent = new Intent(this, AddServerActivity.class); - intent.putExtra(Extra.SERVER, serverId); - startActivityForResult(intent, 0); - } - } - - /** - * Options Menu (Menu Button pressed) - */ - @Override - public boolean onCreateOptionsMenu(Menu menu) - { - super.onCreateOptionsMenu(menu); - - // inflate from xml - MenuInflater inflater = new MenuInflater(this); - inflater.inflate(R.menu.servers, menu); - - return true; - } - - /** - * On menu item selected - */ - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) - { - switch (item.getItemId()) { - case R.id.add: - startActivityForResult(new Intent(this, AddServerActivity.class), 0); - break; - case R.id.about: - startActivity(new Intent(this, AboutActivity.class)); - break; - case R.id.settings: - startActivity(new Intent(this, SettingsActivity.class)); - break; - case R.id.disconnect_all: - ArrayList mServers = Yaaic.getInstance().getServersAsArrayList(); - for (Server server : mServers) { - if (binder.getService().hasConnection(server.getId())) { - server.setStatus(Status.DISCONNECTED); - server.setMayReconnect(false); - binder.getService().getConnection(server.getId()).quitServer(); - } - } - // ugly - binder.getService().stopForegroundCompat(R.string.app_name); - } - - return true; - } - - /** - * On activity result - */ - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) - { - if (resultCode == RESULT_OK) { - // Refresh list from database - adapter.loadServers(); - } - } - - /** - * Delete server - * - * @param serverId - */ - public void deleteServer(int serverId) - { - Database db = new Database(this); - db.removeServerById(serverId); - db.close(); - - Yaaic.getInstance().removeServerById(serverId); - adapter.loadServers(); - } - - /** - * On server status update - */ - @Override - public void onStatusUpdate() - { - adapter.loadServers(); - - if (adapter.getCount() > 2) { - // Hide background if there are servers in the list - list.setBackgroundDrawable(null); - } - } -} diff --git a/app/src/main/java/org/yaaic/adapter/ServerListAdapter.java b/app/src/main/java/org/yaaic/adapter/ServerListAdapter.java deleted file mode 100644 index e1e492a..0000000 --- a/app/src/main/java/org/yaaic/adapter/ServerListAdapter.java +++ /dev/null @@ -1,153 +0,0 @@ -/* -Yaaic - Yet Another Android IRC Client - -Copyright 2009-2013 Sebastian Kaspari - -This file is part of Yaaic. - -Yaaic 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. - -Yaaic 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 Yaaic. If not, see . - */ -package org.yaaic.adapter; - -import java.util.ArrayList; - -import org.yaaic.R; -import org.yaaic.Yaaic; -import org.yaaic.model.Server; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -/** - * Adapter for server lists - * - * @author Sebastian Kaspari - */ -public class ServerListAdapter extends BaseAdapter -{ - private static final int COLOR_CONNECTED = 0xFFbcbcbc; - private static final int COLOR_DISCONNECTED = 0xFF585858; - - private ArrayList servers; - - /** - * Create a new adapter for server lists - */ - public ServerListAdapter() - { - loadServers(); - } - - /** - * Load servers from database - * - * Delegate call to yaaic instance - */ - public void loadServers() - { - servers = Yaaic.getInstance().getServersAsArrayList(); - notifyDataSetChanged(); - } - - /** - * Get number of items - */ - @Override - public int getCount() - { - int size = servers.size(); - - // Display "Add server" item - if (size == 0) { - return 1; - } - - return size; - } - - /** - * Get item at position - * - * @param position - */ - @Override - public Server getItem(int position) - { - if (servers.size() == 0) { - return null; // No server object for the "add server" view - } - - return servers.get(position); - } - - /** - * Get id of item at position - * - * @param position - */ - @Override - public long getItemId(int position) - { - if (servers.size() == 0) { - return 0; - } - - return getItem(position).getId(); - } - - /** - * Get view for item at given position - * - * @param position - * @param convertView - * @param parent - */ - @Override - public View getView(int position, View convertView, ViewGroup parent) - { - Server server = getItem(position); - - LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - if (server == null) { - // Return "Add server" view - return inflater.inflate(R.layout.addserveritem, null); - } - - View v = inflater.inflate(R.layout.serveritem, null); - - TextView titleView = (TextView) v.findViewById(R.id.title); - titleView.setText(server.getTitle()); - - TextView hostView = (TextView) v.findViewById(R.id.host); - hostView.setText(server.getIdentity().getNickname() + " @ " + server.getHost() + " : " + server.getPort()); - - if (server.isConnected()) { - titleView.setTextColor(COLOR_CONNECTED); - hostView.setTextColor(COLOR_CONNECTED); - } else { - titleView.setTextColor(COLOR_DISCONNECTED); - hostView.setTextColor(COLOR_DISCONNECTED); - } - - ((ImageView) v.findViewById(R.id.status)).setImageResource(server.getStatusIcon()); - - return v; - } -} diff --git a/app/src/main/java/org/yaaic/adapter/ServersAdapter.java b/app/src/main/java/org/yaaic/adapter/ServersAdapter.java new file mode 100644 index 0000000..e775ef7 --- /dev/null +++ b/app/src/main/java/org/yaaic/adapter/ServersAdapter.java @@ -0,0 +1,128 @@ +/* +Yaaic - Yet Another Android IRC Client + +Copyright 2009-2013 Sebastian Kaspari + +This file is part of Yaaic. + +Yaaic 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. + +Yaaic 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 Yaaic. If not, see . + */ +package org.yaaic.adapter; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.yaaic.R; +import org.yaaic.Yaaic; +import org.yaaic.menu.ServerPopupMenu; +import org.yaaic.model.Server; + +import java.util.List; + +/** + * RecyclerView adapter for server cards. + */ +public class ServersAdapter extends RecyclerView.Adapter { + public interface ClickListener { + void onServerSelected(Server server); + void onConnectToServer(Server server); + void onDisconnectFromServer(Server server); + void onEditServer(Server server); + void onDeleteServer(Server server); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public final TextView titleView; + public final TextView hostView; + public final View connectionView; + public final View menuView; + public final ServerPopupMenu popupMenu; + + public ViewHolder(View view, ClickListener listener) { + super(view); + + titleView = (TextView) view.findViewById(R.id.title); + hostView = (TextView) view.findViewById(R.id.host); + connectionView = view.findViewById(R.id.connection); + menuView = view.findViewById(R.id.menu); + + popupMenu = new ServerPopupMenu( + view.getContext(), view.findViewById(R.id.menu), + listener + ); + } + } + + private List servers; + private ClickListener listener; + + public ServersAdapter(ClickListener listener) { + this.listener = listener; + + loadServers(); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater. + from(parent.getContext()). + inflate(R.layout.item_server, parent, false); + + return new ViewHolder(view, listener); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + final Server server = servers.get(position); + + int colorResource = server.isConnected() ? R.color.connected : R.color.disconnected; + int color = holder.itemView.getContext().getResources().getColor(colorResource); + + holder.titleView.setText(server.getTitle()); + holder.titleView.setTextColor(color); + holder.connectionView.setBackgroundColor(color); + holder.hostView.setText(String.format("%s @ %s : %d", + server.getIdentity().getNickname(), + server.getHost(), + server.getPort() + )); + + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onServerSelected(server); + } + }); + + holder.popupMenu.updateServer(server); + } + + /** + * Load servers from database + * + * Delegate call to yaaic instance + */ + public void loadServers() { + servers = Yaaic.getInstance().getServersAsArrayList(); + notifyDataSetChanged(); + } + + @Override + public int getItemCount() { + return servers.size(); + } +} diff --git a/app/src/main/java/org/yaaic/fragment/OverviewFragment.java b/app/src/main/java/org/yaaic/fragment/OverviewFragment.java new file mode 100644 index 0000000..a9e4e57 --- /dev/null +++ b/app/src/main/java/org/yaaic/fragment/OverviewFragment.java @@ -0,0 +1,183 @@ +/* +Yaaic - Yet Another Android IRC Client + +Copyright 2009-2015 Sebastian Kaspari + +This file is part of Yaaic. + +Yaaic 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. + +Yaaic 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 Yaaic. If not, see . + */ +package org.yaaic.fragment; + +import android.app.Activity; +import android.app.Fragment; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ImageButton; +import android.widget.Toast; + +import org.yaaic.R; +import org.yaaic.Yaaic; +import org.yaaic.activity.AddServerActivity; +import org.yaaic.adapter.ServersAdapter; +import org.yaaic.db.Database; +import org.yaaic.irc.IRCBinder; +import org.yaaic.irc.IRCService; +import org.yaaic.listener.ServerListener; +import org.yaaic.model.Broadcast; +import org.yaaic.model.Extra; +import org.yaaic.model.Server; +import org.yaaic.model.Status; +import org.yaaic.receiver.ServerReceiver; + +/** + * Fragment showing a list of configured servers. + */ +public class OverviewFragment extends Fragment implements ServerListener, ServersAdapter.ClickListener, View.OnClickListener { + /** + * Callback interface to be implemented by Activities using this fragment. + */ + public interface Callback { + void onServerSelected(Server server); + IRCBinder getBinder(); + } + + private ServersAdapter adapter; + private Callback callback; + private BroadcastReceiver receiver; + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + + if (!(activity instanceof Callback)) { + throw new IllegalArgumentException("Activity has to implement Callback interface"); + } + + this.callback = (Callback) activity; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_servers, container, false); + + adapter = new ServersAdapter(this); + + RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); + + ImageButton button = (ImageButton) view.findViewById(R.id.fab); + button.setOnClickListener(this); + + return view; + } + + @Override + public void onResume() { + super.onResume(); + + receiver = new ServerReceiver(this); + getActivity().registerReceiver(receiver, new IntentFilter(Broadcast.SERVER_UPDATE)); + + adapter.loadServers(); + } + + @Override + public void onPause() { + super.onPause(); + + getActivity().unregisterReceiver(receiver); + } + + @Override + public void onClick(View view) { + final Context context = view.getContext(); + + Intent intent = new Intent(context, AddServerActivity.class); + context.startActivity(intent); + } + + @Override + public void onServerSelected(Server server) { + callback.onServerSelected(server); + } + + @Override + public void onConnectToServer(Server server) { + IRCBinder binder = callback.getBinder(); + + if (binder != null && server.getStatus() == Status.DISCONNECTED) { + binder.connect(server); + server.setStatus(Status.CONNECTING); + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onDisconnectFromServer(Server server) { + IRCBinder binder = callback.getBinder(); + + if (binder != null) { + server.clearConversations(); + server.setStatus(Status.DISCONNECTED); + server.setMayReconnect(false); + binder.getService().getConnection(server.getId()).quitServer(); + } + } + + @Override + public void onEditServer(Server server) { + if (server.getStatus() != Status.DISCONNECTED) { + Toast.makeText(getActivity(), getResources().getString(R.string.disconnect_before_editing), Toast.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(getActivity(), AddServerActivity.class); + intent.putExtra(Extra.SERVER, server.getId()); + startActivityForResult(intent, 0); + } + + } + + @Override + public void onDeleteServer(Server server) { + IRCBinder binder = callback.getBinder(); + + if (binder != null) { + binder.getService().getConnection(server.getId()).quitServer(); + + Database db = new Database(getActivity()); + db.removeServerById(server.getId()); + db.close(); + + Yaaic.getInstance().removeServerById(server.getId()); + adapter.loadServers(); + } + } + + @Override + public void onStatusUpdate() { + adapter.loadServers(); + } +} diff --git a/app/src/main/java/org/yaaic/menu/ServerPopupMenu.java b/app/src/main/java/org/yaaic/menu/ServerPopupMenu.java new file mode 100644 index 0000000..4f72819 --- /dev/null +++ b/app/src/main/java/org/yaaic/menu/ServerPopupMenu.java @@ -0,0 +1,79 @@ +/* +Yaaic - Yet Another Android IRC Client + +Copyright 2009-2013 Sebastian Kaspari + +This file is part of Yaaic. + +Yaaic 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. + +Yaaic 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 Yaaic. If not, see . + */ +package org.yaaic.menu; + +import android.content.Context; +import android.view.MenuItem; +import android.view.View; +import android.widget.PopupMenu; + +import org.yaaic.R; +import org.yaaic.adapter.ServersAdapter; +import org.yaaic.model.Server; + +/** + * Popup menu for the server cards. + */ +public class ServerPopupMenu extends PopupMenu implements PopupMenu.OnMenuItemClickListener, View.OnClickListener { + private Server server; + private ServersAdapter.ClickListener listener; + + public ServerPopupMenu(Context context, View anchor, ServersAdapter.ClickListener listener) { + super(context, anchor); + + this.listener = listener; + + getMenuInflater().inflate(R.menu.context_server, getMenu()); + setOnMenuItemClickListener(this); + + anchor.setOnClickListener(this); + } + + public void updateServer(Server server) { + this.server = server; + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + int id = item.getItemId(); + + switch (id) { + case R.id.edit: + listener.onEditServer(server); + break; + case R.id.delete: + listener.onDeleteServer(server); + break; + case R.id.connect: + listener.onConnectToServer(server); + break; + case R.id.disconnect: + listener.onDisconnectFromServer(server); + break; + } + + return true; + } + + public void onClick(View v) { + show(); + } +} diff --git a/app/src/main/java/org/yaaic/model/Extra.java b/app/src/main/java/org/yaaic/model/Extra.java index 101c5cb..6cb62a5 100644 --- a/app/src/main/java/org/yaaic/model/Extra.java +++ b/app/src/main/java/org/yaaic/model/Extra.java @@ -41,4 +41,7 @@ public class Extra public static final String NICKSERV_PASSWORD = "nickserv_password"; public static final String SASL_USER = "sasl_user"; public static final String SASL_PASSWORD = "sasl_password"; + + public static final String CONNECT = "connect"; + public static final String SERVER_ID = "serverId"; } diff --git a/app/src/main/java/org/yaaic/model/Server.java b/app/src/main/java/org/yaaic/model/Server.java index 368893a..a149444 100644 --- a/app/src/main/java/org/yaaic/model/Server.java +++ b/app/src/main/java/org/yaaic/model/Server.java @@ -409,26 +409,6 @@ public class Server return channels; } - /** - * Get icon for current server status - * - * @return int Status icon ressource - */ - public int getStatusIcon() - { - switch (status) { - case Status.CONNECTED: - return R.drawable.connected; - case Status.DISCONNECTED: - return R.drawable.disconnected; - case Status.PRE_CONNECTING: - case Status.CONNECTING: - return R.drawable.connecting; - } - - return R.drawable.connecting; - } - /** * Get whether a ConversationActivity for this server is currently in the foreground. */ diff --git a/app/src/main/res/drawable-hdpi/ic_action_menu.png b/app/src/main/res/drawable-hdpi/ic_action_menu.png new file mode 100755 index 0000000000000000000000000000000000000000..88d538f5fa38d56c52af8b833eeec3acb46fa799 GIT binary patch literal 294 zcmV+>0oneEP)5eL4jTbG{}}h=t4k)Y^nS} zpWiCs??M1#H*tdl=%rnnm_AiQ0u`{z%Ut-ckOtZ4CJt{Q4YJV|YS^D%szF9eNG1>g sQb0Of1ZWA#1R_8RNQa96Eg_lU34auXF`M2^P5=M^07*qoM6N<$f+#w3_5c6? literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/connected.png b/app/src/main/res/drawable-mdpi/connected.png deleted file mode 100644 index e83d112b7f8793708b3b9695dc70830e46264a24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 454 zcmV;%0XhDOP)|Oi$iIU z{4XH>48$*h_y;b{Oh7EvaG}|K-^)WGFMho<|NZ}uAO{os3t0}a{kvSYbOYs|0r5+i z21X=jD+e72&p!LHbPzv2dDUITf72`Vmj;O)tfPyc=~;KQ%}eigRb;Zy=tFADQBBgj>Ef4wzkU?3dw zcYi)JfCeU5GxNdc2l*NP{bC{}dS3ncE(i-~5b@Vu(*7e*^FN@?gbiTgcn>81z%+y0 z`jvs1_X5N3mqvv2DzM652CIk0E!Z_aLZ)jN{sYqkKFq-I{=VNuP>j4n*8G06)7n*f z{O0{Ycl=}kdH@46vOG2uw48~Y(vTAgIE5u1P4QgtY;y?1&sU~Eg9L%1FL=0A_J0n% wjW>nC052%s(bD!8XsSX<+l-XtDu4h30LP5773fj0-~a#s07*qoM6N<$f`XsRPXGV_ diff --git a/app/src/main/res/drawable-mdpi/connecting.png b/app/src/main/res/drawable-mdpi/connecting.png deleted file mode 100644 index f93a0067e4a4d6c585ccacf0c92bf361c0bb1ab8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 498 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipP# z4KNHR8w`~I00DAIL_t(2&!v;iD+F;E$3HVW+mhX7TC*fM&|aKGUM{YdQZB3f11=nt z+{K9;$OSpO$jN~sxp}G8k`lF2yJ67Uw7d4D-5Hme8XH4A_3c+refmAmx9=n9y3Suq z`l9Cs>Wo(c3P1`_f!uen2sB)utOir+amZZ}?UsahxuAK~bfNXIduU|=cmSSEK(LJ6 z65g2{m!*R-hcoLcA19kp;#p_!Mtg8>8F;k9^2PqlsN!0mx7#t7^Cp`6uKIv0ASW7q zzpJzxa=H`P$y0mh3vZ810gAb^08}ad(~jRbTwi_EW|)ZtI9_6B)#MR>16O+DvT3vg zl$559x2GF4!*SaZT_k~`3F|;c@^M~_(f$+ssHEYtWArXOw$lmloqh~f$jMAy;$fAHM25JuLdXlyY oGs^?`%d(v|QuQg@!hf#n1H;glo4@UJ1poj507*qoM6N<$g8t{&LjV8( diff --git a/app/src/main/res/drawable-mdpi/disconnected.png b/app/src/main/res/drawable-mdpi/disconnected.png deleted file mode 100644 index a77059b0df0d91a4e2716e65087848ded4c585a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 440 zcmV;p0Z0CcP)|Oi$iIU z{4XH>48$*h_y;b{Oh7Dk`0!!(M~@zb{P^+1{NKNSg3Qd!FSxk4_D4iSbOYs|0r5+i z21X=jE3aL(_-q+t@({ zqT@e*{>Z+1^(qypRuYIgkTr`vd-g2k@87=+`0(%Fzl9esUR(lHFADQBBM@_c|Nh;W zm=ON@^{W9iFu|IcA3l7@4|FaQF`9wS7lZ{gi1;fnFaHtftba(}zzLX`nBIfTfcY5| z++SH)SuX%>XCQ<*I5;kY)FTJjD+vjSHH0(*!TZ$I)J~9kWXkO=p;lMnJX81OK^W|d&o zlvfvMMkeeVE$F ZzTkF(;$zLFOMp&b@O1TaS?83{1OUHTJWK!p literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_action_menu.png b/app/src/main/res/drawable-xhdpi/ic_action_menu.png new file mode 100755 index 0000000000000000000000000000000000000000..7d69251193c9e8f485b48877b40612c20de3ca46 GIT binary patch literal 394 zcmV;50d@X~P)8ig~Ur z&CZ|y*ZaJZfKXzKF=?xLH-*mr`D>MKBj&7=|Yixj!{&RsEXh`NPr$ z<^qi4_?}W~&or5*X?jKgLj}wo5IzEzHo=_p+q$klh6eCC3I2)jaQqp}Id83-KL~9e z0n6!LQwssEQRzRwg9ALK3k$#kumCI&7KUJf3qM3)0b>w?1%M%F5FB=aAy@zwfCXRy zSm1;LA+E-_7f2~_FW~Vb@=Q&agHT2Na}>q_HQCW)EjYkK^_ptpfSRV^u@)TQp?Xa< oaX?Me@K_5D@KC*`n&BPr3;n#_L6^Bf%K!iX07*qoM6N<$g7^NRng9R* literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_menu.png b/app/src/main/res/drawable-xxhdpi/ic_action_menu.png new file mode 100755 index 0000000000000000000000000000000000000000..f61f9cb6d8b453c839493b99f998bd86cae4921f GIT binary patch literal 715 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V4CFV;uum9_jabCpOd4A>wkx* zOdP!L8XeM4yRC^~Tsw8G_J$(GTUo60Z5^B=8boW1kIffQes=Z=zd1ku*E2CYp5K*B zi(B!-LzW|`^oTY?M>o)D0c(Y6>Wq|99_0x(a`#&V(iB@>TkOu9RT>(qUmClA`TAvZ zA8Ii!zW5@`K;lgF+ilvwS}pY?3@EB{)hmR;-Q--u4@p^C7Cl=v>XlW{WMLaV%5JNv+t-V)ZMHQl;&&y99-U*@vm(6 zQ>8E~okHtZ-+ylwb1|vge}8|~&-e9j`d70|VOt#`&%kxP--MBYVIy-=r4WRg&bdHY zZIzT&lG5Yo$kV|s%i|hWFXxbZEE8fcyRm7)iw;qf>zhm%bo4}Jk}VseEB$R5&A&77 zJ#4y~8+&UKlmFHCuktly4YOy?OO%n_XguRjyviM!L({of7?L(IFf`m?+-Sqe;INCi z%Z}1mMakDYZ#MPSOUrKLx#aWnF5`609V#;z p1TM2MFdX6Qc + + + \ No newline at end of file diff --git a/app/src/main/res/layout/addserveritem.xml b/app/src/main/res/layout/addserveritem.xml deleted file mode 100644 index 136fa56..0000000 --- a/app/src/main/res/layout/addserveritem.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/app/src/main/res/layout/fragment_servers.xml b/app/src/main/res/layout/fragment_servers.xml new file mode 100644 index 0000000..ed5041f --- /dev/null +++ b/app/src/main/res/layout/fragment_servers.xml @@ -0,0 +1,40 @@ + + + + + + + diff --git a/app/src/main/res/layout/item_server.xml b/app/src/main/res/layout/item_server.xml new file mode 100644 index 0000000..df062e7 --- /dev/null +++ b/app/src/main/res/layout/item_server.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/serveritem.xml b/app/src/main/res/layout/serveritem.xml deleted file mode 100644 index 649fc20..0000000 --- a/app/src/main/res/layout/serveritem.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/servers.xml b/app/src/main/res/layout/servers.xml index f06b401..2f28257 100644 --- a/app/src/main/res/layout/servers.xml +++ b/app/src/main/res/layout/servers.xml @@ -19,7 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Yaaic. If not, see . --> - @@ -27,4 +27,4 @@ along with Yaaic. If not, see . android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> - + diff --git a/app/src/main/res/menu/context_server.xml b/app/src/main/res/menu/context_server.xml new file mode 100644 index 0000000..21ed7d4 --- /dev/null +++ b/app/src/main/res/menu/context_server.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/servers.xml b/app/src/main/res/menu/servers.xml deleted file mode 100644 index 71d158e..0000000 --- a/app/src/main/res/menu/servers.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 03dc99b..5de8ce0 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -9,4 +9,8 @@ #B6B6B6 #FFC107 #EEEEEE + + #FFFFFF + #4CAF50 + #F44336 \ No newline at end of file