From 180a85ed9b09ff6baad8b0adefdb6b7fdeac6a97 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Fri, 19 Feb 2016 23:38:31 +0100 Subject: [PATCH] Rewrote the drawer handling --- app/build.gradle | 1 + .../de/kuschku/libquassel/client/Client.java | 13 +- .../libquassel/client/NetworkManager.java | 1 - .../libquassel/localtypes/BacklogFilter.java | 5 +- .../libquassel/localtypes/buffers/Buffer.java | 3 +- .../localtypes/buffers/ChannelBuffer.java | 9 +- .../localtypes/buffers/QueryBuffer.java | 11 +- .../localtypes/buffers/StatusBuffer.java | 8 +- .../types/abstracts/AIgnoreListManager.java | 5 +- .../types/impl/BufferViewConfig.java | 20 ++ .../types/interfaces/QBacklogManager.java | 8 +- .../types/interfaces/QBufferViewConfig.java | 4 + .../chat/BufferViewConfigSpinnerAdapter.java | 125 ++++++++++ .../ui/chat/ChannelDetailActivity.java | 15 +- .../quasseldroid_ng/ui/chat/MainActivity.java | 154 ++++++------ .../ui/chat/drawer/BufferItem.java | 152 ------------ .../ui/chat/drawer/BufferItemManager.java | 81 ------- .../chat/drawer/BufferViewConfigAdapter.java | 226 ++++++++++++++++++ .../ui/chat/drawer/BufferViewConfigItem.java | 139 ----------- .../ui/chat/drawer/BufferViewHolder.java | 165 +++++++++++++ .../ui/chat/drawer/NetworkItem.java | 141 +++++------ .../NetworkViewHolder.java} | 36 ++- .../ui/chat/drawer/NickListWrapper.java | 152 ------------ .../OnBufferClickListener.java} | 15 +- .../ui/chat/util/LayoutHelperPhoneImpl.java | 50 ---- .../ui/chat/util/LayoutHelperTabletImpl.java | 55 ----- .../quasseldroid_ng/ui/theme/ThemeUtil.java | 43 ++++ app/src/main/res/drawable/badge.xml | 30 +++ .../main/res/layout-w720dp/activity_main.xml | 42 +++- .../res/layout/activity_channel_detail.xml | 30 +-- app/src/main/res/layout/activity_main.xml | 67 +++++- app/src/main/res/layout/fragment_chat.xml | 3 +- app/src/main/res/layout/fragment_loading.xml | 3 +- app/src/main/res/layout/widget_buffer.xml | 103 ++++++++ app/src/main/res/layout/widget_network.xml | 55 +++++ app/src/main/res/values/strings.xml | 1 + 36 files changed, 1101 insertions(+), 870 deletions(-) create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItem.java delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItemManager.java create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigItem.java create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewHolder.java rename app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/{util/ILayoutHelper.java => drawer/NetworkViewHolder.java} (51%) delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NickListWrapper.java rename app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/{util/ActivityImplFactory.java => drawer/OnBufferClickListener.java} (70%) delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperPhoneImpl.java delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperTabletImpl.java create mode 100644 app/src/main/res/drawable/badge.xml create mode 100644 app/src/main/res/layout/widget_buffer.xml create mode 100644 app/src/main/res/layout/widget_network.xml diff --git a/app/build.gradle b/app/build.gradle index 7417cde86..4502d0f3e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -147,6 +147,7 @@ dependencies { compile 'org.joda:joda-convert:1.8' // UI Libs + compile 'com.bignerdranch.android:expandablerecyclerview:2.0.4' compile(name:'library-release', ext:'aar') compile('com.mikepenz:materialdrawer:5.0.0.b27-SNAPSHOT@aar') { transitive = true } compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') { transitive = true } diff --git a/app/src/main/java/de/kuschku/libquassel/client/Client.java b/app/src/main/java/de/kuschku/libquassel/client/Client.java index 0bb973ed7..09fd97c12 100644 --- a/app/src/main/java/de/kuschku/libquassel/client/Client.java +++ b/app/src/main/java/de/kuschku/libquassel/client/Client.java @@ -212,34 +212,32 @@ public class Client extends AClient { public Object unsafe_getObjectByIdentifier(@NonNull String className, @NonNull String objectName) { switch (className) { case "AliasManager": { - assertNotNull(aliasManager); return aliasManager; } case "BacklogManager": { - assertNotNull(backlogManager); return backlogManager; } case "BufferSyncer": { - assertNotNull(bufferSyncer); return bufferSyncer; } case "BufferViewConfig": { - assertNotNull(bufferViewManager); + if (bufferViewManager == null) + return null; + return bufferViewManager.bufferViewConfig(Integer.parseInt(objectName)); } case "BufferViewManager": { - assertNotNull(bufferViewManager); return bufferViewManager; } case "CoreInfo": { - assertNotNull(coreInfo); return coreInfo; } case "Identity": { + if (identityManager == null) + return null; return identityManager.identity(Integer.parseInt(objectName)); } case "IgnoreListManager": { - assertNotNull(ignoreListManager); return ignoreListManager; } case "IrcChannel": { @@ -272,7 +270,6 @@ public class Client extends AClient { return networkManager.network(Integer.parseInt(objectName)); } case "NetworkConfig": { - assertNotNull(globalNetworkConfig); return globalNetworkConfig; } case "NetworkInfo": { diff --git a/app/src/main/java/de/kuschku/libquassel/client/NetworkManager.java b/app/src/main/java/de/kuschku/libquassel/client/NetworkManager.java index 27ca0a816..51e23bbde 100644 --- a/app/src/main/java/de/kuschku/libquassel/client/NetworkManager.java +++ b/app/src/main/java/de/kuschku/libquassel/client/NetworkManager.java @@ -68,7 +68,6 @@ public class NetworkManager extends Observable { public void init(@NonNull List<Integer> networkIds) { for (int networkId : networkIds) { - createNetwork(networkId); client.requestInitObject("Network", String.valueOf(networkId)); } } diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java index ffe87c6a6..340eedadb 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java @@ -39,6 +39,8 @@ import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; import de.kuschku.util.observables.callbacks.UICallback; import de.kuschku.util.observables.lists.ObservableComparableSortedList; +import static de.kuschku.util.AndroidAssert.assertNotNull; + public class BacklogFilter implements UICallback { @NonNull private final Client client; @@ -92,7 +94,8 @@ public class BacklogFilter implements UICallback { } private boolean filterItem(@NonNull Message message) { - QNetwork network = client.networkManager().network(message.bufferInfo.networkId()); + QNetwork network = client.networkManager().network(client.bufferManager().buffer(message.bufferInfo.id()).getInfo().networkId()); + assertNotNull(network); return (client.ignoreListManager() != null && client.ignoreListManager().matches(message, network)) || filteredTypes.contains(message.type); } diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffer.java b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffer.java index 849f5d13d..67ec5c9b4 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffer.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/Buffer.java @@ -21,6 +21,7 @@ package de.kuschku.libquassel.localtypes.buffers; +import android.databinding.ObservableField; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -36,7 +37,7 @@ public interface Buffer { String getName(); @NonNull - BufferInfo.BufferStatus getStatus(); + ObservableField<BufferInfo.BufferStatus> getStatus(); void renameBuffer(@NonNull String newName); diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/ChannelBuffer.java b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/ChannelBuffer.java index fada32de0..cf00f0ce0 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/ChannelBuffer.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/ChannelBuffer.java @@ -21,6 +21,7 @@ package de.kuschku.libquassel.localtypes.buffers; +import android.databinding.ObservableField; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -34,6 +35,8 @@ public class ChannelBuffer implements Buffer { @NonNull private BufferInfo info; + private ObservableField<BufferInfo.BufferStatus> status = new ObservableField<>(); + public ChannelBuffer(@NonNull BufferInfo info, @NonNull Client client) { this.info = info; this.client = client; @@ -58,8 +61,10 @@ public class ChannelBuffer implements Buffer { @NonNull @Override - public BufferInfo.BufferStatus getStatus() { - return getChannel() == null ? BufferInfo.BufferStatus.OFFLINE : BufferInfo.BufferStatus.ONLINE; + public ObservableField<BufferInfo.BufferStatus> getStatus() { + // FIXME: Make this dynamic + status.set(getChannel() == null ? BufferInfo.BufferStatus.OFFLINE : BufferInfo.BufferStatus.ONLINE); + return status; } @Override diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/QueryBuffer.java b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/QueryBuffer.java index e373eade1..89a507257 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/QueryBuffer.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/QueryBuffer.java @@ -21,6 +21,7 @@ package de.kuschku.libquassel.localtypes.buffers; +import android.databinding.ObservableField; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -34,6 +35,8 @@ public class QueryBuffer implements Buffer { @NonNull private BufferInfo info; + private ObservableField<BufferInfo.BufferStatus> status = new ObservableField<>(); + public QueryBuffer(@NonNull BufferInfo info, @NonNull Client client) { this.info = info; this.client = client; @@ -58,10 +61,12 @@ public class QueryBuffer implements Buffer { @NonNull @Override - public BufferInfo.BufferStatus getStatus() { - return (getUser() == null) ? BufferInfo.BufferStatus.OFFLINE : + public ObservableField<BufferInfo.BufferStatus> getStatus() { + // FIXME: Make this dynamic + status.set((getUser() == null) ? BufferInfo.BufferStatus.OFFLINE : (getUser().isAway()) ? BufferInfo.BufferStatus.AWAY : - BufferInfo.BufferStatus.ONLINE; + BufferInfo.BufferStatus.ONLINE); + return status; } @Override diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/StatusBuffer.java b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/StatusBuffer.java index ec75adde3..5828b6306 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/StatusBuffer.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/buffers/StatusBuffer.java @@ -21,6 +21,7 @@ package de.kuschku.libquassel.localtypes.buffers; +import android.databinding.ObservableField; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -33,6 +34,7 @@ public class StatusBuffer implements Buffer { private final Client client; @NonNull private BufferInfo info; + private ObservableField<BufferInfo.BufferStatus> status = new ObservableField<>(); public StatusBuffer(@NonNull BufferInfo info, @NonNull Client client) { this.info = info; @@ -62,8 +64,10 @@ public class StatusBuffer implements Buffer { @NonNull @Override - public BufferInfo.BufferStatus getStatus() { - return getNetwork().isConnected() ? BufferInfo.BufferStatus.ONLINE : BufferInfo.BufferStatus.OFFLINE; + public ObservableField<BufferInfo.BufferStatus> getStatus() { + // FIXME: Make this dynamic + status.set(getNetwork().isConnected() ? BufferInfo.BufferStatus.ONLINE : BufferInfo.BufferStatus.OFFLINE); + return status; } @NonNull diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java index 9c8773597..2677b2004 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java @@ -28,6 +28,8 @@ import de.kuschku.libquassel.syncables.types.SyncableObject; import de.kuschku.libquassel.syncables.types.interfaces.QIgnoreListManager; import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; +import static de.kuschku.util.AndroidAssert.assertNotNull; + public abstract class AIgnoreListManager<T extends AIgnoreListManager<T>> extends SyncableObject<T> implements QIgnoreListManager { @Override public void requestRemoveIgnoreListItem(String ignoreRule) { @@ -76,7 +78,8 @@ public abstract class AIgnoreListManager<T extends AIgnoreListManager<T>> extend } @Override - public boolean matches(@NonNull Message message, @NonNull QNetwork network) { + public boolean matches(Message message, QNetwork network) { + assertNotNull(network); return match(message.content, message.sender, message.type, network.networkName(), message.bufferInfo.name()) != StrictnessType.UnmatchedStrictness; } } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java index 0fee0b05e..2c5f8ae23 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java @@ -32,6 +32,7 @@ import de.kuschku.libquassel.client.Client; import de.kuschku.libquassel.primitives.types.QVariant; import de.kuschku.libquassel.syncables.serializers.BufferViewConfigSerializer; import de.kuschku.libquassel.syncables.types.abstracts.ABufferViewConfig; +import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; import de.kuschku.util.observables.lists.ObservableList; import de.kuschku.util.observables.lists.ObservableSet; @@ -46,6 +47,7 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> { private final ObservableSet<Integer> removedBuffers; @NonNull private final ObservableSet<Integer> temporarilyRemovedBuffers; + private final ObservableSet<QNetwork> networkList = new ObservableSet<>(); private int bufferViewId; private String bufferViewName; private int networkId; @@ -120,9 +122,21 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> { @Override public void _setNetworkId(int networkId) { this.networkId = networkId; + updateNetworks(); _update(); } + @Override + public void updateNetworks() { + if (this.networkId == 0) { + networkList.retainAll(client.networkManager().networks()); + networkList.addAll(client.networkManager().networks()); + } else { + networkList.retainAll(Collections.singleton(client.networkManager().network(this.networkId))); + networkList.add(client.networkManager().network(this.networkId)); + } + } + @Override public boolean addNewBuffersAutomatically() { return addNewBuffersAutomatically; @@ -330,6 +344,7 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> { bufferViewId = Integer.parseInt(objectName); super.init(objectName, provider, client); client.bufferViewManager()._addBufferViewConfig(this); + updateNetworks(); _update(); } @@ -338,6 +353,11 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> { bufferViewId = bufferViewConfigId; } + @Override + public ObservableSet<QNetwork> networkList() { + return networkList; + } + @Override public void _update(@NonNull Map<String, QVariant> from) { _update(BufferViewConfigSerializer.get().fromLegacy(from)); diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java index 9ab862b60..dcbadf289 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java @@ -42,9 +42,9 @@ public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncable void _requestBacklog(int id, int first, int last, int limit, int additional); @Synced - void receiveBacklog(int id, int first, int last, int limit, int additional, List<Message> messages); + void receiveBacklog(int id, int first, int last, int limit, int additional, @NonNull List<Message> messages); - void _receiveBacklog(int id, int first, int last, int limit, int additional, List<Message> messages); + void _receiveBacklog(int id, int first, int last, int limit, int additional, @NonNull List<Message> messages); @Synced void requestBacklogAll(int first, int last, int limit, int additional); @@ -52,9 +52,9 @@ public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncable void _requestBacklogAll(int first, int last, int limit, int additional); @Synced - void receiveBacklogAll(int first, int last, int limit, int additional, List<Message> messages); + void receiveBacklogAll(int first, int last, int limit, int additional, @NonNull List<Message> messages); - void _receiveBacklogAll(int first, int last, int limit, int additional, List<Message> messages); + void _receiveBacklogAll(int first, int last, int limit, int additional, @NonNull List<Message> messages); @NonNull BacklogFilter filter(int id); diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java index 640099fc0..f73fe9ea1 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java @@ -152,4 +152,8 @@ public interface QBufferViewConfig extends QObservable { void _requestRemoveBufferPermanently(final int bufferId); void init(int bufferViewConfigId); + + ObservableSet<QNetwork> networkList(); + + void updateNetworks(); } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java new file mode 100644 index 000000000..7a1eda952 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java @@ -0,0 +1,125 @@ +/* + * QuasselDroid - Quassel client for Android + * Copyright (C) 2016 Janne Koschinski + * Copyright (C) 2016 Ken Børge Viktil + * Copyright (C) 2016 Magnus Fjell + * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid_ng.ui.chat; + +import android.content.res.Resources; +import android.database.DataSetObserver; +import android.support.annotation.Nullable; +import android.support.v7.view.ContextThemeWrapper; +import android.support.v7.widget.ThemedSpinnerAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.HashSet; +import java.util.Set; + +import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig; +import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager; +import de.kuschku.quasseldroid_ng.ui.theme.AppContext; + +public class BufferViewConfigSpinnerAdapter implements ThemedSpinnerAdapter { + private final AppContext context; + private final QBufferViewManager bufferViewManager; + @Nullable + private Resources.Theme theme; + + private Set<DataSetObserver> observers = new HashSet<>(); + + public BufferViewConfigSpinnerAdapter(AppContext context, QBufferViewManager bufferViewManager) { + this.context = context; + this.bufferViewManager = bufferViewManager; + } + + @Nullable + @Override + public Resources.Theme getDropDownViewTheme() { + return theme; + } + + @Override + public void setDropDownViewTheme(@Nullable Resources.Theme theme) { + this.theme = theme; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(new ContextThemeWrapper(parent.getContext(), theme)); + TextView view = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, parent, false); + view.setText(((QBufferViewConfig) getItem(position)).bufferViewName()); + return view; + } + + @Override + public void registerDataSetObserver(DataSetObserver observer) { + observers.add(observer); + } + + @Override + public void unregisterDataSetObserver(DataSetObserver observer) { + observers.remove(observer); + } + + @Override + public int getCount() { + return bufferViewManager.bufferViewConfigs().size(); + } + + @Override + public Object getItem(int position) { + return bufferViewManager.bufferViewConfigs().get(position); + } + + @Override + public long getItemId(int position) { + return ((QBufferViewConfig) getItem(position)).bufferViewId(); + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(new ContextThemeWrapper(parent.getContext(), theme)); + TextView view = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, parent, false); + view.setText(((QBufferViewConfig) getItem(position)).bufferViewName()); + return view; + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public boolean isEmpty() { + return getCount() == 0; + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java index 01c7d2e16..05746007d 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java @@ -21,6 +21,7 @@ package de.kuschku.quasseldroid_ng.ui.chat; +import android.graphics.Typeface; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.widget.AppCompatButton; @@ -30,7 +31,6 @@ import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import butterknife.Bind; import butterknife.ButterKnife; @@ -77,9 +77,16 @@ public class ChannelDetailActivity extends BoundActivity { QIrcChannel channel = buffer.getChannel(); if (channel == null) return; - if (channel.topic() != null) - topic.setText(new IrcFormatHelper(context).formatIrcMessage(context.client(), channel.topic(), buffer.getInfo(), v -> finish())); - topic.setMovementMethod(LinkMovementMethod.getInstance()); + if (channel.topic() == null) { + topic.setText(R.string.no_topic_set); + topic.setTextColor(context.themeUtil().res.colorForegroundSecondary); + topic.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC)); + } else { + topic.setText(new IrcFormatHelper(context).formatIrcMessage(context.client(), channel.topic(), buffer.getInfo(), v -> finish())); + topic.setMovementMethod(LinkMovementMethod.getInstance()); + topic.setTextColor(context.themeUtil().res.colorForeground); + topic.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL)); + } toolbar.setTitle(channel.name()); setSupportActionBar(toolbar); diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java index cc112f621..4295df4a8 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java @@ -23,24 +23,26 @@ package de.kuschku.quasseldroid_ng.ui.chat; import android.content.Intent; import android.os.Bundle; -import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.AppCompatEditText; +import android.support.v7.widget.AppCompatSpinner; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.FrameLayout; +import android.widget.AdapterView; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; -import com.mikepenz.materialdrawer.AccountHeader; -import com.mikepenz.materialdrawer.AccountHeaderBuilder; -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import java.util.ArrayList; import java.util.Arrays; @@ -60,19 +62,13 @@ import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer; import de.kuschku.libquassel.localtypes.buffers.QueryBuffer; import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager; -import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig; -import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager; import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel; import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser; import de.kuschku.quasseldroid_ng.R; import de.kuschku.quasseldroid_ng.service.ClientBackgroundThread; -import de.kuschku.quasseldroid_ng.ui.chat.drawer.BufferItem; -import de.kuschku.quasseldroid_ng.ui.chat.drawer.BufferViewConfigItem; -import de.kuschku.quasseldroid_ng.ui.chat.drawer.NetworkItem; +import de.kuschku.quasseldroid_ng.ui.chat.drawer.BufferViewConfigAdapter; import de.kuschku.quasseldroid_ng.ui.chat.fragment.ChatFragment; import de.kuschku.quasseldroid_ng.ui.chat.fragment.LoadingFragment; -import de.kuschku.quasseldroid_ng.ui.chat.util.ActivityImplFactory; -import de.kuschku.quasseldroid_ng.ui.chat.util.ILayoutHelper; import de.kuschku.quasseldroid_ng.ui.chat.util.Status; import de.kuschku.util.accounts.Account; import de.kuschku.util.accounts.AccountManager; @@ -83,17 +79,21 @@ import de.kuschku.util.servicebound.BoundActivity; import static de.kuschku.util.AndroidAssert.assertNotNull; public class MainActivity extends BoundActivity { - - /** - * A helper to handle the different layout implementations - */ - ILayoutHelper layoutHelper; - /** * Host layout for content fragment, for example showing a loader or the chat */ - @Bind(R.id.content_host) - FrameLayout contentHost; + @Bind(R.id.chatList) + RecyclerView chatList; + + @Bind(R.id.chatListSpinner) + AppCompatSpinner chatListSpinner; + + @Bind(R.id.chatListToolbar) + Toolbar chatListToolbar; + + @Nullable + @Bind(R.id.drawer_layout) + DrawerLayout drawerLayout; /** * Main ActionBar @@ -101,28 +101,17 @@ public class MainActivity extends BoundActivity { @Bind(R.id.toolbar) Toolbar toolbar; - /** - * The left material drawer of this activity, depending on layout either in the layout hierarchy - * or at the left as pull-out menu - */ - Drawer drawerLeft; - - /** - * AccountHeader field for the bufferviewconfig header - */ - AccountHeader accountHeader; - /** * This object encapsulates the current status of the activity – opened bufferview, for example */ private Status status = new Status(); - private BufferViewConfigItem currentConfig; - private AccountManager manager; private ToolbarWrapper toolbarWrapper; + private BufferViewConfigAdapter chatListAdapter; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -131,26 +120,33 @@ public class MainActivity extends BoundActivity { toolbarWrapper = new ToolbarWrapper(toolbar); toolbarWrapper.setOnClickListener(v -> { if (context.client() != null) { - Intent intent = new Intent(this, ChannelDetailActivity.class); - intent.putExtra("buffer", context.client().backlogManager().open()); - startActivity(intent); + int id = context.client().backlogManager().open(); + Buffer buffer = context.client().bufferManager().buffer(id); + if (buffer instanceof ChannelBuffer) { + Intent intent = new Intent(this, ChannelDetailActivity.class); + intent.putExtra("buffer", id); + startActivity(intent); + } } }); setSupportActionBar(toolbar); - layoutHelper = ActivityImplFactory.of(getResources().getBoolean(R.bool.isTablet), this); - accountHeader = buildAccountHeader(); - drawerLeft = layoutHelper.buildDrawer(savedInstanceState, accountHeader, toolbar); - drawerLeft.setOnDrawerItemClickListener((view, position, drawerItem) -> { - if (drawerItem instanceof NetworkItem) { - drawerLeft.getAdapter().toggleExpandable(position); - return true; - } else if (drawerItem instanceof BufferItem) { - int id = ((BufferItem) drawerItem).getBuffer().getInfo().id(); - context.client().backlogManager().open(id); - return false; + chatListAdapter = BufferViewConfigAdapter.of(context); + chatListAdapter.setBufferClickListener(buffer -> { + if (context.client() != null) { + context.client().backlogManager().open(buffer.getInfo().id()); + if (drawerLayout != null) + drawerLayout.closeDrawer(GravityCompat.START); } - return true; }); + chatList.setItemAnimator(new DefaultItemAnimator()); + chatList.setLayoutManager(new LinearLayoutManager(this)); + chatList.setAdapter(chatListAdapter); + + DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + if (drawerLayout != null) { + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.material_drawer_open, R.string.material_drawer_close); + toggle.syncState(); + } replaceFragment(new LoadingFragment()); @@ -222,6 +218,8 @@ public class MainActivity extends BoundActivity { finish(); } + /* + private AccountHeader buildAccountHeader() { return new AccountHeaderBuilder() .withActivity(this) @@ -235,16 +233,16 @@ public class MainActivity extends BoundActivity { .build(); } + */ + public void onEventMainThread(ConnectionChangeEvent event) { onConnectionChange(event.status); } public void onConnectionChange(ConnectionChangeEvent.Status status) { if (status == ConnectionChangeEvent.Status.CONNECTED) { - updateBufferViewConfigs(); - context.client().backlogManager().open(this.status.bufferId); - accountHeader.setActiveProfile(this.status.bufferViewConfigId, true); replaceFragment(new ChatFragment()); + onConnected(); } else if (status == ConnectionChangeEvent.Status.DISCONNECTED) { Toast.makeText(getApplication(), context.themeUtil().translations.statusDisconnected, Toast.LENGTH_LONG).show(); } @@ -289,33 +287,10 @@ public class MainActivity extends BoundActivity { } } } - drawerLeft.setSelection(id, false); } - private void selectBufferViewConfig(@IntRange(from = -1) int bufferViewConfigId) { - assertNotNull(drawerLeft); - assertNotNull(accountHeader); - Client client = context.client(); - assertNotNull(client); - - drawerLeft.removeAllItems(); - - status.bufferViewConfigId = bufferViewConfigId; - accountHeader.setActiveProfile(bufferViewConfigId, false); - - if (currentConfig != null) - currentConfig.remove(); - currentConfig = null; - - QBufferViewManager bufferViewManager = client.bufferViewManager(); - if (bufferViewConfigId != -1 && bufferViewManager != null) { - QBufferViewConfig viewConfig = bufferViewManager.bufferViewConfig(bufferViewConfigId); - if (viewConfig != null) { - currentConfig = new BufferViewConfigItem(drawerLeft, viewConfig, context); - } - } - } + /* private void updateBufferViewConfigs() { assertNotNull(context.client().bufferViewManager()); List<QBufferViewConfig> bufferViews = context.client().bufferViewManager().bufferViewConfigs(); @@ -334,6 +309,7 @@ public class MainActivity extends BoundActivity { } accountHeader.setActiveProfile(status.bufferViewConfigId, true); } + */ @Override protected void onConnectToThread(@Nullable ClientBackgroundThread thread) { @@ -342,14 +318,32 @@ public class MainActivity extends BoundActivity { connectToServer(manager.account(context.settings().lastAccount.get())); else { if (context.client() != null) { - context.client().backlogManager().init("", context.provider(), context.client()); - context.client().backlogManager().open(status.bufferId); - updateBuffer(context.client().backlogManager().open()); - accountHeader.setActiveProfile(status.bufferViewConfigId, true); + onConnected(); } } } + private void onConnected() { + context.client().backlogManager().init("", context.provider(), context.client()); + context.client().backlogManager().open(status.bufferId); + if (context.client().bufferViewManager() != null) { + chatListSpinner.setAdapter(new BufferViewConfigSpinnerAdapter(context, context.client().bufferViewManager())); + chatListSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + chatListAdapter.selectConfig((int) id); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + chatListAdapter.selectConfig(-1); + } + }); + } + updateBuffer(context.client().backlogManager().open()); + // accountHeader.setActiveProfile(status.bufferViewConfigId, true); + } + // FIXME: Fix this ugly hack public void displayFilterDialog() { if (context.client() != null) { diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItem.java deleted file mode 100644 index dd27587a6..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItem.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.drawer; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.View; -import android.widget.TextView; - -import com.mikepenz.materialdrawer.holder.ColorHolder; -import com.mikepenz.materialdrawer.holder.ImageHolder; -import com.mikepenz.materialdrawer.holder.StringHolder; -import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; - -import de.kuschku.libquassel.localtypes.buffers.Buffer; -import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer; -import de.kuschku.libquassel.localtypes.buffers.QueryBuffer; -import de.kuschku.libquassel.localtypes.buffers.StatusBuffer; -import de.kuschku.libquassel.message.Message; -import de.kuschku.libquassel.primitives.types.BufferInfo; -import de.kuschku.quasseldroid_ng.R; -import de.kuschku.quasseldroid_ng.ui.theme.AppContext; - -public class BufferItem extends SecondaryDrawerItem { - @NonNull - private final Buffer buffer; - @NonNull - private final AppContext context; - - public BufferItem(@NonNull Buffer buffer, @NonNull AppContext context) { - this.buffer = buffer; - this.context = context; - } - - @Override - public StringHolder getDescription() { - if (buffer instanceof QueryBuffer) { - QueryBuffer queryBuffer = (QueryBuffer) buffer; - if (queryBuffer.getUser() != null) - return new StringHolder(queryBuffer.getUser().realName()); - } else if (buffer instanceof StatusBuffer) { - - } else if (buffer instanceof ChannelBuffer) { - ChannelBuffer channelBuffer = (ChannelBuffer) buffer; - if (channelBuffer.getChannel() != null) - return new StringHolder(channelBuffer.getChannel().topic()); - } - return super.getDescription(); - } - - @Nullable - @Override - public StringHolder getName() { - if (buffer instanceof StatusBuffer) - return new StringHolder(context.themeUtil().translations.titleStatusBuffer); - else - return new StringHolder(buffer.getName()); - } - - @NonNull - @Override - public ImageHolder getIcon() { - if (buffer instanceof ChannelBuffer) { - if (buffer.getStatus() != BufferInfo.BufferStatus.OFFLINE) { - return new ImageHolder(R.drawable.ic_status_channel); - } else { - return new ImageHolder(R.drawable.ic_status_channel_offline); - } - } else if (buffer instanceof StatusBuffer) { - if (buffer.getStatus() != BufferInfo.BufferStatus.OFFLINE) { - return new ImageHolder(R.drawable.ic_status); - } else { - return new ImageHolder(R.drawable.ic_status_offline); - } - } else { - if (buffer.getStatus() != BufferInfo.BufferStatus.OFFLINE) { - return new ImageHolder(R.drawable.ic_status); - } else { - return new ImageHolder(R.drawable.ic_status_offline); - } - } - } - - @Override - public boolean isIconTinted() { - return buffer.getStatus() == BufferInfo.BufferStatus.ONLINE; - } - - @NonNull - @Override - public ColorHolder getIconColor() { - return buffer.getStatus() == BufferInfo.BufferStatus.ONLINE ? - ColorHolder.fromColor(context.themeUtil().res.colorAccent) : - new ColorHolder(); - } - - @NonNull - @Override - public ColorHolder getDescriptionTextColor() { - return ColorHolder.fromColor(context.themeUtil().res.colorForegroundSecondary); - } - - @NonNull - @Override - public ColorHolder getTextColor() { - int type = context.client().bufferSyncer().activity(buffer.getInfo().id()); - if ((type & Message.Type.Plain.value) != 0 || (type & Message.Type.Notice.value) != 0) - return ColorHolder.fromColor(context.themeUtil().res.colorTintMessage); - else if ((type & ~Message.Type.DayChange.value) != 0) - return ColorHolder.fromColor(context.themeUtil().res.colorTintActivity); - else - return ColorHolder.fromColor(context.themeUtil().res.colorForeground); - } - - @NonNull - public Buffer getBuffer() { - return buffer; - } - - @Override - public long getIdentifier() { - return buffer.getInfo().id(); - } - - @Override - public void onPostBindView(IDrawerItem drawerItem, View view) { - super.onPostBindView(drawerItem, view); - - if (getDescription() != null && getDescription().getText() != null) - ((TextView) view.findViewById(R.id.material_drawer_description)).setText(context.deserializer().formatString(getDescription().getText())); - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItemManager.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItemManager.java deleted file mode 100644 index b4e597569..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferItemManager.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.drawer; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import java.util.HashMap; -import java.util.Map; - -import de.kuschku.quasseldroid_ng.ui.theme.AppContext; -import de.kuschku.util.observables.IObservable; -import de.kuschku.util.observables.callbacks.ElementCallback; -import de.kuschku.util.observables.callbacks.wrappers.MultiElementCallbackWrapper; - -public class BufferItemManager implements ElementCallback<Integer>, IObservable<ElementCallback<BufferItem>> { - - private final MultiElementCallbackWrapper<BufferItem> callback = MultiElementCallbackWrapper.<BufferItem>of(); - - @Nullable - private final AppContext context; - private final Map<Integer, BufferItem> items = new HashMap<>(); - - public BufferItemManager(@Nullable AppContext context) { - this.context = context; - context.client().bufferManager().bufferIds().addCallback(this); - for (Integer id : context.client().bufferManager().bufferIds()) { - notifyItemInserted(id); - } - } - - public BufferItem get(int bufferId) { - return items.get(bufferId); - } - - @Override - public void notifyItemInserted(Integer element) { - if (!items.containsKey(element)) { - BufferItem item = new BufferItem(context.client().bufferManager().buffer(element), context); - items.put(element, item); - callback.notifyItemInserted(item); - } - } - - @Override - public void notifyItemRemoved(Integer element) { - callback.notifyItemRemoved(items.remove(element)); - } - - @Override - public void notifyItemChanged(Integer element) { - callback.notifyItemChanged(items.get(element)); - } - - public void addCallback(@NonNull ElementCallback<BufferItem> callback) { - this.callback.addCallback(callback); - } - - public void removeCallback(@NonNull ElementCallback<BufferItem> callback) { - this.callback.removeCallback(callback); - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java new file mode 100644 index 000000000..2d1983fa4 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java @@ -0,0 +1,226 @@ +/* + * QuasselDroid - Quassel client for Android + * Copyright (C) 2016 Janne Koschinski + * Copyright (C) 2016 Ken Børge Viktil + * Copyright (C) 2016 Magnus Fjell + * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid_ng.ui.chat.drawer; + +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter; +import com.bignerdranch.expandablerecyclerview.Model.ParentListItem; + +import java.lang.ref.WeakReference; +import java.util.Map; +import java.util.WeakHashMap; + +import de.kuschku.libquassel.localtypes.buffers.Buffer; +import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig; +import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; +import de.kuschku.quasseldroid_ng.ui.theme.AppContext; +import de.kuschku.util.observables.callbacks.ElementCallback; +import de.kuschku.util.observables.callbacks.UICallback; +import de.kuschku.util.observables.lists.ObservableSortedList; + +public class BufferViewConfigAdapter extends ExpandableRecyclerAdapter<NetworkViewHolder, BufferViewHolder> implements OnBufferClickListener { + private final AppContext context; + private final ObservableSortedList<NetworkItem> items; + private final Map<QNetwork, NetworkItem> itemMap = new WeakHashMap<>(); + private final Map<Integer, BufferViewHolder> bufferViewHolderMap = new WeakHashMap<>(); + private QBufferViewConfig config; + private WeakReference<RecyclerView> recyclerView = new WeakReference<>(null); + private int selectedFrom; + private int selectedTo; + private int open; + private OnBufferClickListener bufferClickListener; + + private ElementCallback<QNetwork> callback = new ElementCallback<QNetwork>() { + @Override + public void notifyItemInserted(QNetwork network) { + NetworkItem networkItem = new NetworkItem(context, config, network); + itemMap.put(network, networkItem); + items.add(networkItem); + } + + @Override + public void notifyItemRemoved(QNetwork network) { + items.remove(itemMap.remove(network)); + } + + @Override + public void notifyItemChanged(QNetwork network) { + items.notifyItemChanged(items.indexOf(itemMap.get(network))); + } + }; + + private BufferViewConfigAdapter(AppContext context, ObservableSortedList<NetworkItem> items) { + super(items); + this.context = context; + this.items = items; + items.addCallback(new UICallback() { + @Override + public void notifyItemInserted(int position) { + notifyParentItemInserted(position); + } + + @Override + public void notifyItemChanged(int position) { + notifyParentItemChanged(position); + } + + @Override + public void notifyItemRemoved(int position) { + notifyParentItemRemoved(position); + } + + @Override + public void notifyItemMoved(int from, int to) { + notifyParentItemRemoved(from); + notifyParentItemInserted(to); + } + + @Override + public void notifyItemRangeInserted(int position, int count) { + notifyParentItemRangeInserted(position, count); + } + + @Override + public void notifyItemRangeChanged(int position, int count) { + for (int i = position; i < position + count; i++) { + notifyParentItemChanged(i); + } + } + + @Override + public void notifyItemRangeRemoved(int position, int count) { + for (int i = position; i < position + count; i++) { + notifyParentItemRemoved(position); + } + } + }); + } + + public static BufferViewConfigAdapter of(AppContext context) { + final ObservableSortedList<NetworkItem> networkItems = new ObservableSortedList<>(NetworkItem.class, new ObservableSortedList.ItemComparator<NetworkItem>() { + @Override + public int compare(NetworkItem o1, NetworkItem o2) { + return o1.getNetwork().networkName().compareTo(o2.getNetwork().networkName()); + } + + @Override + public boolean areContentsTheSame(NetworkItem oldItem, NetworkItem newItem) { + return oldItem == newItem; + } + + @Override + public boolean areItemsTheSame(NetworkItem item1, NetworkItem item2) { + return item1.getNetwork().networkId() == item2.getNetwork().networkId(); + } + }); + return new BufferViewConfigAdapter(context, networkItems); + } + + @Override + public NetworkViewHolder onCreateParentViewHolder(ViewGroup parentViewGroup) { + LayoutInflater inflater = LayoutInflater.from(parentViewGroup.getContext()); + return new NetworkViewHolder(inflater.inflate(NetworkViewHolder.layout(), parentViewGroup, false)); + } + + @Override + public BufferViewHolder onCreateChildViewHolder(ViewGroup childViewGroup) { + LayoutInflater inflater = LayoutInflater.from(childViewGroup.getContext()); + return new BufferViewHolder(context, inflater.inflate(BufferViewHolder.layout(), childViewGroup, false)); + } + + @Override + public void onBindParentViewHolder(NetworkViewHolder parentViewHolder, int position, ParentListItem parentListItem) { + parentViewHolder.bind(context, (NetworkItem) parentListItem); + } + + @Override + public void onBindChildViewHolder(BufferViewHolder childViewHolder, int position, Object childListItem) { + bufferViewHolderMap.remove(childViewHolder.id); + childViewHolder.bind(this, (Buffer) childListItem); + bufferViewHolderMap.put(childViewHolder.id, childViewHolder); + } + + @Override + public void onClick(Buffer buffer) { + if (bufferClickListener != null) { + bufferClickListener.onClick(buffer); + } + } + + public void setBufferClickListener(OnBufferClickListener bufferClickListener) { + this.bufferClickListener = bufferClickListener; + } + + public void setRecyclerView(RecyclerView recyclerView) { + this.recyclerView = new WeakReference<>(recyclerView); + } + + public void selectConfig(int id) { + QBufferViewConfig newconfig = context.client().bufferViewManager().bufferViewConfig(id); + int firstVisible = -1; + if (newconfig == config) { + RecyclerView list = recyclerView.get(); + if (list != null) { + LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager(); + firstVisible = layoutManager.findFirstVisibleItemPosition(); + } + } + + if (config != null) + config.networkList().removeCallback(callback); + config = newconfig; + config.updateNetworks(); + items.clear(); + itemMap.clear(); + for (QNetwork network : config.networkList()) { + NetworkItem networkItem = new NetworkItem(context, config, network); + itemMap.put(network, networkItem); + items.add(networkItem); + } + config.networkList().addCallback(callback); + if (firstVisible != -1) { + RecyclerView list = recyclerView.get(); + if (list != null) { + LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager(); + layoutManager.scrollToPosition(firstVisible); + } + } + } + + public void setSelection(int from, int to) { + + } + + public void setOpen(int id) { + BufferViewHolder old = bufferViewHolderMap.get(open); + if (old != null) old.setSelected(false); + else bufferViewHolderMap.remove(open); + BufferViewHolder now = bufferViewHolderMap.get(id); + if (now != null) now.setSelected(true); + else bufferViewHolderMap.remove(id); + open = id; + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigItem.java deleted file mode 100644 index ba724a1de..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigItem.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.drawer; - -import android.support.annotation.NonNull; - -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; - -import java.util.HashSet; -import java.util.Set; - -import de.kuschku.libquassel.client.Client; -import de.kuschku.libquassel.client.NetworkManager; -import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig; -import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; -import de.kuschku.quasseldroid_ng.ui.theme.AppContext; -import de.kuschku.util.observables.callbacks.DrawerItemCallback; -import de.kuschku.util.observables.callbacks.GeneralCallback; -import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper; -import de.kuschku.util.observables.lists.ObservableComparableSortedList; - -import static de.kuschku.util.AndroidAssert.assertNotNull; - -public class BufferViewConfigItem implements DrawerItemCallback { - @NonNull - private final BufferItemManager manager; - @NonNull - private final ObservableComparableSortedList<NetworkItem> networks = new ObservableComparableSortedList<>(NetworkItem.class); - @NonNull - private final Drawer drawer; - @NonNull - private final QBufferViewConfig config; - @NonNull - private final AppContext context; - - GeneralCallback rebuildNetworkList = this::rebuildNetworkList; - AdapterUICallbackWrapper callbackWrapper; - - public BufferViewConfigItem(@NonNull Drawer drawer, @NonNull QBufferViewConfig config, @NonNull AppContext context) { - this.drawer = drawer; - this.config = config; - this.context = context; - manager = new BufferItemManager(context); - config.addObserver(rebuildNetworkList); - assertNotNull(drawer.getItemAdapter()); - callbackWrapper = new AdapterUICallbackWrapper(drawer.getItemAdapter()); - networks.addCallback(callbackWrapper); - rebuildNetworkList(); - } - - private void rebuildNetworkList() { - Client client = context.client(); - assertNotNull(client); - NetworkManager networkManager = client.networkManager(); - assertNotNull(networkManager); - - // First we build a list of all network ids we want to display - Set<Integer> ids = new HashSet<>(); - for (QNetwork network : networkManager.networks()) { - if (config.networkId() <= 0 || network.networkId() == config.networkId()) { - ids.add(network.networkId()); - } - } - // Now we build a list of all items to remove - Set<NetworkItem> removed = new HashSet<>(); - for (NetworkItem item : networks) { - if (item.getNetwork() != null && ids.contains(item.getNetwork().networkId())) { - // And make sure that ids only contains those networks added - ids.remove(item.getNetwork().networkId()); - } else { - removed.add(item); - item.removeCallback(this); - } - } - - // By now we know that removed contains all removed networks, and ids all added ones - // We do this to avoid concurrent modification and to reduce the amount of UI changes - networks.removeAll(removed); - for (IDrawerItem item : removed) { - drawer.removeItem(item.getIdentifier()); - } - for (int id : ids) { - QNetwork network = networkManager.network(id); - if (network != null) { - NetworkItem item = new NetworkItem(config, client, manager, network); - networks.add(item); - item.addCallback(this); - } - } - for (NetworkItem item : networks) { - if (ids.contains(item.getNetwork().networkId())) { - int position = networks.indexOf(item); - drawer.getItemAdapter().add(position, item); - } - } - for (int i = 0; i < drawer.getAdapter().getItemCount(); i++) { - IDrawerItem adapterItem = drawer.getAdapter().getItem(i); - if (adapterItem instanceof NetworkItem && - ((NetworkItem) adapterItem).getNetwork().isConnected() && - ids.contains(((NetworkItem) adapterItem).getNetwork().networkId())) - drawer.getAdapter().expand(i); - } - } - - @Override - public void notifyChanged(@NonNull IDrawerItem item) { - int position = drawer.getAdapter().getPosition(item); - if (position != -1) { - drawer.getAdapter().notifyAdapterItemChanged(position); - if (item instanceof NetworkItem) - drawer.getAdapter().notifyAdapterSubItemsChanged(position); - } - } - - public void remove() { - config.deleteObserver(rebuildNetworkList); - networks.removeCallback(callbackWrapper); - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewHolder.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewHolder.java new file mode 100644 index 000000000..b2179c9b6 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewHolder.java @@ -0,0 +1,165 @@ +/* + * QuasselDroid - Quassel client for Android + * Copyright (C) 2016 Janne Koschinski + * Copyright (C) 2016 Ken Børge Viktil + * Copyright (C) 2016 Magnus Fjell + * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + * + * This program 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. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid_ng.ui.chat.drawer; + +import android.databinding.Observable; +import android.databinding.ObservableField; +import android.graphics.drawable.StateListDrawable; +import android.support.annotation.LayoutRes; +import android.support.annotation.Nullable; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.bignerdranch.expandablerecyclerview.ViewHolder.ChildViewHolder; +import com.mikepenz.materialize.util.UIUtils; + +import java.util.Locale; + +import butterknife.Bind; +import butterknife.ButterKnife; +import de.kuschku.libquassel.events.BufferChangeEvent; +import de.kuschku.libquassel.localtypes.buffers.Buffer; +import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer; +import de.kuschku.libquassel.localtypes.buffers.QueryBuffer; +import de.kuschku.libquassel.primitives.types.BufferInfo; +import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel; +import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser; +import de.kuschku.quasseldroid_ng.R; +import de.kuschku.quasseldroid_ng.ui.theme.AppContext; + +public class BufferViewHolder extends ChildViewHolder { + + public int id; + @Bind(R.id.material_drawer_icon) + ImageView icon; + @Bind(R.id.material_drawer_badge) + TextView badge; + @Bind(R.id.material_drawer_badge_container) + LinearLayout badgeContainer; + @Bind(R.id.material_drawer_name) + TextView name; + @Bind(R.id.material_drawer_description) + TextView description; + private ObservableField<BufferInfo.BufferStatus> status; + private Observable.OnPropertyChangedCallback callback; + private AppContext context; + + private StateListDrawable background; + + public BufferViewHolder(AppContext context, View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + this.context = context; + context.provider().event.registerSticky(this); + + background = new StateListDrawable(); + background.addState(new int[]{android.R.attr.state_selected}, itemView.getResources().getDrawable(com.mikepenz.materialdrawer.R.color.material_drawer_selected)); + background.addState(new int[0], UIUtils.getSelectableBackground(itemView.getContext())); + } + + @LayoutRes + public static int layout() { + return R.layout.widget_buffer; + } + + public void bind(OnBufferClickListener listener, Buffer buffer) { + if (status != null) + status.removeOnPropertyChangedCallback(callback); + status = buffer.getStatus(); + name.setText(buffer.getName()); + setDescription(context.deserializer().formatString(getDescription(buffer))); + setBadge(0); + itemView.setOnClickListener(v -> listener.onClick(buffer)); + + itemView.setBackground(background); + + id = buffer.getInfo().id(); + + BufferInfo.Type type = buffer.getInfo().type(); + setIcon(context, type, status); + callback = new Observable.OnPropertyChangedCallback() { + @Override + public void onPropertyChanged(Observable sender, int propertyId) { + setIcon(context, type, status); + } + }; + status.addOnPropertyChangedCallback(callback); + + setSelected(); + } + + private void setSelected() { + setSelected(context.client().backlogManager().open() == id); + } + + public void setSelected(boolean selected) { + itemView.setSelected(selected); + } + + private void setIcon(AppContext context, BufferInfo.Type type, ObservableField<BufferInfo.BufferStatus> status) { + icon.setImageDrawable(context.themeUtil().statusDrawables.of(type, status.get())); + } + + private void setDescription(@Nullable CharSequence description) { + if (description == null || description.length() == 0) { + this.description.setText(null); + this.description.setVisibility(View.GONE); + } else { + this.description.setText(description); + this.description.setVisibility(View.VISIBLE); + } + } + + private void setBadge(int count) { + if (count == 0) { + badgeContainer.setVisibility(View.GONE); + badge.setText("0"); + } else { + badgeContainer.setVisibility(View.VISIBLE); + badge.setText(String.format(Locale.US, "%d", count)); + } + } + + @Nullable + private String getDescription(Buffer buffer) { + if (buffer instanceof ChannelBuffer) { + ChannelBuffer channelBuffer = (ChannelBuffer) buffer; + QIrcChannel channel = channelBuffer.getChannel(); + if (channel != null) { + return channel.topic(); + } + } else if (buffer instanceof QueryBuffer) { + QueryBuffer queryBuffer = (QueryBuffer) buffer; + QIrcUser user = queryBuffer.getUser(); + if (user != null) { + return user.realName(); + } + } + return null; + } + + public void onEventMainThread(BufferChangeEvent event) { + setSelected(); + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java index 9a21ffcfc..3b989be83 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java @@ -21,108 +21,92 @@ package de.kuschku.quasseldroid_ng.ui.chat.drawer; -import android.support.annotation.NonNull; +import com.bignerdranch.expandablerecyclerview.Model.ParentListItem; -import com.mikepenz.materialdrawer.holder.StringHolder; -import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; - -import java.util.ArrayList; import java.util.List; -import de.kuschku.libquassel.client.Client; +import de.kuschku.libquassel.localtypes.buffers.Buffer; +import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig; import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; -import de.kuschku.util.observables.ContentComparable; -import de.kuschku.util.observables.IObservable; -import de.kuschku.util.observables.callbacks.DrawerItemCallback; +import de.kuschku.quasseldroid_ng.ui.theme.AppContext; +import de.kuschku.util.irc.IrcCaseMapper; import de.kuschku.util.observables.callbacks.ElementCallback; -import de.kuschku.util.observables.callbacks.wrappers.MultiDrawerItemCallback; +import de.kuschku.util.observables.lists.ObservableSortedList; -public class NetworkItem extends PrimaryDrawerItem implements IObservable<DrawerItemCallback>, ContentComparable<NetworkItem> { - @NonNull - private final QBufferViewConfig config; - @NonNull - private final Client client; - @NonNull - private final BufferItemManager manager; - @NonNull +public class NetworkItem implements ParentListItem { private final QNetwork network; - private final MultiDrawerItemCallback callback = MultiDrawerItemCallback.of(); + private final ObservableSortedList<Buffer> buffers = new ObservableSortedList<>(Buffer.class, new ObservableSortedList.ItemComparator<Buffer>() { + @Override + public int compare(Buffer o1, Buffer o2) { + if (o1.getInfo().type() == o2.getInfo().type()) { + return IrcCaseMapper.toLowerCase(o1.getName()).compareTo(IrcCaseMapper.toLowerCase(o2.getName())); + } else { + if (o1.getInfo().type() == BufferInfo.Type.STATUS) + return -1; + else if (o2.getInfo().type() == BufferInfo.Type.STATUS) + return 1; + else if (o1.getInfo().type() == BufferInfo.Type.CHANNEL) + return -1; + else if (o2.getInfo().type() == BufferInfo.Type.CHANNEL) + return 1; + else if (o1.getInfo().type() == BufferInfo.Type.GROUP) + return -1; + else if (o2.getInfo().type() == BufferInfo.Type.GROUP) + return 1; + else + return -1; + } + } + + @Override + public boolean areContentsTheSame(Buffer oldItem, Buffer newItem) { + return oldItem == newItem; + } + + @Override + public boolean areItemsTheSame(Buffer item1, Buffer item2) { + return item1.getInfo().id() == item2.getInfo().id(); + } + }); - public NetworkItem(@NonNull QBufferViewConfig config, @NonNull Client client, @NonNull BufferItemManager manager, @NonNull QNetwork network) { - this.config = config; - this.client = client; - this.manager = manager; + public NetworkItem(AppContext context, QBufferViewConfig config, QNetwork network) { this.network = network; - ElementCallback<Integer> elemCallback = new ElementCallback<Integer>() { + for (int id : config.bufferList()) { + Buffer buffer = context.client().bufferManager().buffer(id); + if (buffer != null && buffer.getInfo().networkId() == network.networkId()) + buffers.add(buffer); + } + config.bufferIds().addCallback(new ElementCallback<Integer>() { @Override - public void notifyItemInserted(Integer element) { - callback.notifyChanged(NetworkItem.this); + public void notifyItemInserted(Integer id) { + Buffer buffer = context.client().bufferManager().buffer(id); + if (buffer != null && buffer.getInfo().networkId() == network.networkId()) + buffers.add(buffer); } @Override - public void notifyItemRemoved(Integer element) { - callback.notifyChanged(NetworkItem.this); + public void notifyItemRemoved(Integer id) { + buffers.remove(context.client().bufferManager().buffer(id)); } @Override - public void notifyItemChanged(Integer element) { - callback.notifyChanged(manager.get(element)); - } - }; - config.bufferIds().addCallback(elemCallback); - client.bufferManager().byNetwork(network.networkId()).addCallback(elemCallback); - } - - @NonNull - @Override - public List<IDrawerItem> getSubItems() { - List<IDrawerItem> bufferItems = new ArrayList<>(); - for (int id : config.bufferList()) { - if (client.bufferManager().byNetwork(network.networkId()).contains(id)) { - if (config.allowedBufferTypes() == 0 || - config.allowedBufferTypes() == -1 || - (config.allowedBufferTypes() & client.bufferManager().buffer(id).getInfo().type().id) != 0) - - bufferItems.add(manager.get(id)); + public void notifyItemChanged(Integer id) { + buffers.notifyItemChanged(buffers.indexOf(context.client().bufferManager().buffer(id))); } - } - return bufferItems; + }); } - @NonNull @Override - public StringHolder getName() { - return new StringHolder(network.networkName()); + public List<?> getChildItemList() { + return buffers; } @Override - public void addCallback(DrawerItemCallback callback) { - this.callback.addCallback(callback); + public boolean isInitiallyExpanded() { + return network.isConnected(); } - @Override - public void removeCallback(DrawerItemCallback callback) { - this.callback.removeCallback(callback); - } - - @Override - public boolean areItemsTheSame(@NonNull NetworkItem other) { - return network.networkId() == other.network.networkId(); - } - - @Override - public boolean areContentsTheSame(NetworkItem other) { - return network.equals(other); - } - - @Override - public int compareTo(@NonNull NetworkItem another) { - return network.networkName().compareToIgnoreCase(another.network.networkName()); - } - - @NonNull public QNetwork getNetwork() { return network; } @@ -131,9 +115,4 @@ public class NetworkItem extends PrimaryDrawerItem implements IObservable<Drawer public String toString() { return String.valueOf(network); } - - @Override - public long getIdentifier() { - return network.networkId() << 16; - } } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ILayoutHelper.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkViewHolder.java similarity index 51% rename from app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ILayoutHelper.java rename to app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkViewHolder.java index feb431580..3151de82b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ILayoutHelper.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkViewHolder.java @@ -19,15 +19,35 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.quasseldroid_ng.ui.chat.util; +package de.kuschku.quasseldroid_ng.ui.chat.drawer; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.Toolbar; +import android.support.annotation.LayoutRes; +import android.view.View; +import android.widget.TextView; -import com.mikepenz.materialdrawer.AccountHeader; -import com.mikepenz.materialdrawer.Drawer; +import com.bignerdranch.expandablerecyclerview.ViewHolder.ParentViewHolder; -public interface ILayoutHelper { - Drawer buildDrawer(@Nullable Bundle savedInstanceState, AccountHeader accountHeader, Toolbar toolbar); +import butterknife.Bind; +import butterknife.ButterKnife; +import de.kuschku.quasseldroid_ng.R; +import de.kuschku.quasseldroid_ng.ui.theme.AppContext; + +public class NetworkViewHolder extends ParentViewHolder { + + @Bind(R.id.material_drawer_name) + TextView name; + + public NetworkViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + + @LayoutRes + public static int layout() { + return R.layout.widget_network; + } + + public void bind(AppContext context, NetworkItem item) { + name.setText(item.getNetwork().networkName()); + } } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NickListWrapper.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NickListWrapper.java deleted file mode 100644 index 0e55bf39a..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NickListWrapper.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.drawer; - -import android.support.annotation.NonNull; - -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.holder.BadgeStyle; -import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; -import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; - -import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel; -import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser; -import de.kuschku.util.backports.Objects; -import de.kuschku.util.irc.IrcCaseMapper; -import de.kuschku.util.observables.callbacks.ElementCallback; -import de.kuschku.util.observables.callbacks.UICallback; -import de.kuschku.util.observables.lists.ObservableSortedList; - -public class NickListWrapper { - @NonNull - private final QIrcChannel channel; - private final ObservableSortedList<QIrcUser> list = new ObservableSortedList<>(QIrcUser.class, new ObservableSortedList.ItemComparator<QIrcUser>() { - @Override - public int compare(@NonNull QIrcUser o1, @NonNull QIrcUser o2) { - int indexa = channel.network().modeToIndex(channel.userModes(o1)); - int indexb = channel.network().modeToIndex(channel.userModes(o2)); - if (indexa == indexb) { - return o1.nick().compareToIgnoreCase(o2.nick()); - } else { - return indexa - indexb; - } - } - - @Override - public boolean areContentsTheSame(QIrcUser oldItem, QIrcUser newItem) { - return oldItem == newItem; - } - - @Override - public boolean areItemsTheSame(@NonNull QIrcUser item1, @NonNull QIrcUser item2) { - return Objects.equals(item1.hostmask(), item2.hostmask()); - } - }); - - public NickListWrapper(@NonNull Drawer drawerRight, @NonNull QIrcChannel channel) { - drawerRight.removeAllItems(); - this.channel = channel; - for (String nick : channel.users()) { - list.add(channel.network().ircUser(nick)); - } - channel.users().addCallback(new ElementCallback<String>() { - @Override - public void notifyItemInserted(String element) { - list.add(channel.network().ircUser(element)); - } - - @Override - public void notifyItemRemoved(String element) { - for (QIrcUser user : list) { - if (IrcCaseMapper.equalsIgnoreCase(user.nick(), element)) { - list.remove(user); - return; - } - } - } - - @Override - public void notifyItemChanged(String element) { - for (int i = 0; i < list.size(); i++) { - if (IrcCaseMapper.equalsIgnoreCase(list.get(i).nick(), element)) { - list.notifyItemChanged(i); - return; - } - } - } - }); - this.list.addCallback(new UICallback() { - @Override - public void notifyItemInserted(int position) { - drawerRight.getItemAdapter().add(position, fromUser(list.get(position))); - } - - @Override - public void notifyItemChanged(int position) { - drawerRight.getItemAdapter().notifyItemChanged(position); - } - - @Override - public void notifyItemRemoved(int position) { - drawerRight.removeItemByPosition(position); - } - - @Override - public void notifyItemMoved(int from, int to) { - notifyItemRemoved(from); - notifyItemInserted(from); - } - - @Override - public void notifyItemRangeInserted(int position, int count) { - for (int i = position; i < position + count; i++) { - notifyItemInserted(i); - } - } - - @Override - public void notifyItemRangeChanged(int position, int count) { - for (int i = position; i < position + count; i++) { - notifyItemChanged(i); - } - } - - @Override - public void notifyItemRangeRemoved(int position, int count) { - for (int i = position; i < position + count; i++) { - notifyItemRemoved(i); - } - } - }); - for (QIrcUser user : list) { - if (user != null) - drawerRight.getItemAdapter().add(fromUser(user)); - } - } - - private IDrawerItem fromUser(@NonNull QIrcUser user) { - return new PrimaryDrawerItem() - .withName(user.nick()) - .withBadge(channel.network().modeToPrefix(channel.userModes(user))) - .withBadgeStyle(new BadgeStyle().withColor(0xFFFF0000).withTextColor(0xFFFFFFFF)); - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ActivityImplFactory.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/OnBufferClickListener.java similarity index 70% rename from app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ActivityImplFactory.java rename to app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/OnBufferClickListener.java index 26e7f29fa..c5d505cf1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/ActivityImplFactory.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/OnBufferClickListener.java @@ -19,17 +19,10 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.quasseldroid_ng.ui.chat.util; +package de.kuschku.quasseldroid_ng.ui.chat.drawer; -import de.kuschku.quasseldroid_ng.ui.chat.MainActivity; +import de.kuschku.libquassel.localtypes.buffers.Buffer; -public class ActivityImplFactory { - private ActivityImplFactory() { - - } - - - public static ILayoutHelper of(boolean tablet, MainActivity activity) { - return (tablet) ? new LayoutHelperTabletImpl(activity) : new LayoutHelperPhoneImpl(activity); - } +public interface OnBufferClickListener { + void onClick(Buffer buffer); } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperPhoneImpl.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperPhoneImpl.java deleted file mode 100644 index a8b777570..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperPhoneImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.util; - -import android.os.Bundle; -import android.support.v7.widget.Toolbar; - -import com.mikepenz.materialdrawer.AccountHeader; -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.DrawerBuilder; - -import de.kuschku.quasseldroid_ng.ui.chat.MainActivity; - -public class LayoutHelperPhoneImpl implements ILayoutHelper { - private final MainActivity activity; - - public LayoutHelperPhoneImpl(MainActivity activity) { - this.activity = activity; - } - - @Override - public Drawer buildDrawer(Bundle savedInstanceState, AccountHeader accountHeader, Toolbar toolbar) { - return new DrawerBuilder() - .withActivity(activity) - .withToolbar(toolbar) - .withAccountHeader(accountHeader) - .withTranslucentStatusBar(true) - .withSavedInstance(savedInstanceState) - .build(); - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperTabletImpl.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperTabletImpl.java deleted file mode 100644 index 3ced622bc..000000000 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/LayoutHelperTabletImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * QuasselDroid - Quassel client for Android - * Copyright (C) 2016 Janne Koschinski - * Copyright (C) 2016 Ken Børge Viktil - * Copyright (C) 2016 Magnus Fjell - * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid_ng.ui.chat.util; - -import android.os.Bundle; -import android.support.v7.widget.Toolbar; -import android.widget.FrameLayout; - -import com.mikepenz.materialdrawer.AccountHeader; -import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.DrawerBuilder; - -import de.kuschku.quasseldroid_ng.R; -import de.kuschku.quasseldroid_ng.ui.chat.MainActivity; - -public class LayoutHelperTabletImpl implements ILayoutHelper { - private final MainActivity activity; - - public LayoutHelperTabletImpl(MainActivity activity) { - this.activity = activity; - } - - @Override - public Drawer buildDrawer(Bundle savedInstanceState, AccountHeader accountHeader, Toolbar toolbar) { - Drawer drawer = new DrawerBuilder() - .withActivity(activity) - .withToolbar(toolbar) - .withAccountHeader(accountHeader) - .withTranslucentStatusBar(false) - .withSavedInstance(savedInstanceState) - .buildView(); - FrameLayout drawerHost = (FrameLayout) activity.findViewById(R.id.drawer_host); - drawerHost.addView(drawer.getSlider()); - return drawer; - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/theme/ThemeUtil.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/theme/ThemeUtil.java index c847f05c6..759bf7441 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/theme/ThemeUtil.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/theme/ThemeUtil.java @@ -22,13 +22,16 @@ package de.kuschku.quasseldroid_ng.ui.theme; import android.content.Context; +import android.graphics.drawable.Drawable; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.view.ContextThemeWrapper; import de.kuschku.libquassel.events.ConnectionChangeEvent; +import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.quasseldroid_ng.R; import de.kuschku.util.annotationbind.AutoBinder; import de.kuschku.util.annotationbind.AutoColor; @@ -45,14 +48,18 @@ public class ThemeUtil { public final FormatStrings translations = new FormatStrings(); @NonNull public final DateTimeFormatHelper formatter; + @NonNull + public final StatusDrawables statusDrawables; public ThemeUtil(@NonNull Context ctx) { initColors(new ContextThemeWrapper(ctx, ctx.getTheme())); + statusDrawables = new StatusDrawables(ctx, res); formatter = new DateTimeFormatHelper(ctx); } public ThemeUtil(@NonNull Context ctx, @NonNull AppTheme theme) { initColors(new ContextThemeWrapper(ctx, theme.themeId)); + statusDrawables = new StatusDrawables(ctx, res); formatter = new DateTimeFormatHelper(ctx); } @@ -82,6 +89,42 @@ public class ThemeUtil { } } + public static class StatusDrawables { + public final Drawable online; + public final Drawable away; + public final Drawable offline; + + public final Drawable channelOnline; + public final Drawable channelOffline; + + public StatusDrawables(Context ctx, Colors colors) { + online = ctx.getResources().getDrawable(R.drawable.ic_status); + DrawableCompat.setTint(online, colors.colorAccent); + away = ctx.getResources().getDrawable(R.drawable.ic_status); + offline = ctx.getResources().getDrawable(R.drawable.ic_status_offline); + + channelOnline = ctx.getResources().getDrawable(R.drawable.ic_status_channel); + DrawableCompat.setTint(channelOnline, colors.colorAccent); + channelOffline = ctx.getResources().getDrawable(R.drawable.ic_status_channel_offline); + } + + public Drawable of(BufferInfo.Type type, BufferInfo.BufferStatus status) { + if (type == BufferInfo.Type.CHANNEL) { + if (status == BufferInfo.BufferStatus.ONLINE) + return channelOnline; + else + return channelOffline; + } else { + if (status == BufferInfo.BufferStatus.ONLINE) + return online; + else if (status == BufferInfo.BufferStatus.AWAY) + return away; + else + return offline; + } + } + } + public static class FormatStrings { @AutoString(R.string.usernameHostmask) public String usernameHostmask; diff --git a/app/src/main/res/drawable/badge.xml b/app/src/main/res/drawable/badge.xml new file mode 100644 index 000000000..568414bec --- /dev/null +++ b/app/src/main/res/drawable/badge.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ QuasselDroid - Quassel client for Android + ~ Copyright (C) 2016 Janne Koschinski + ~ Copyright (C) 2016 Ken Børge Viktil + ~ Copyright (C) 2016 Magnus Fjell + ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + ~ + ~ This program 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. + ~ + ~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/md_red_500" /> + <padding + android:bottom="10dp" + android:left="10dp" + android:right="10dp" + android:top="10dp" /> + <corners android:radius="6dp" /> +</shape> diff --git a/app/src/main/res/layout-w720dp/activity_main.xml b/app/src/main/res/layout-w720dp/activity_main.xml index 2193aacb6..5f40523c2 100644 --- a/app/src/main/res/layout-w720dp/activity_main.xml +++ b/app/src/main/res/layout-w720dp/activity_main.xml @@ -22,17 +22,48 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" - android:orientation="horizontal" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="?attr/colorBackground" + android:orientation="horizontal" tools:context=".ui.chat.MainActivity"> - <FrameLayout - android:id="@+id/drawer_host" + <LinearLayout android:layout_width="300dp" - android:layout_height="match_parent" /> + android:layout_height="match_parent" + android:orientation="vertical"> + + <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <android.support.v7.widget.Toolbar + android:id="@+id/chatListToolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:theme="@style/AppTheme.AppBarOverlay" + app:popupTheme="@style/AppTheme.PopupOverlay"> + + <android.support.v7.widget.AppCompatSpinner + android:id="@+id/chatListSpinner" + android:layout_width="fill_parent" + android:layout_height="match_parent" /> + + </android.support.v7.widget.Toolbar> + + </android.support.design.widget.AppBarLayout> + + <android.support.v7.widget.RecyclerView + android:id="@+id/chatList" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </LinearLayout> <LinearLayout android:layout_width="match_parent" @@ -47,4 +78,5 @@ android:layout_height="match_parent" /> </LinearLayout> + </LinearLayout> diff --git a/app/src/main/res/layout/activity_channel_detail.xml b/app/src/main/res/layout/activity_channel_detail.xml index ba7bba87b..9b08044c7 100644 --- a/app/src/main/res/layout/activity_channel_detail.xml +++ b/app/src/main/res/layout/activity_channel_detail.xml @@ -20,7 +20,6 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/colorBackground" @@ -52,11 +51,11 @@ style="@style/TextAppearance.AppCompat.Button" android:layout_width="match_parent" android:layout_height="48dp" - android:textColor="?attr/colorAccent" - android:text="Topic" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:gravity="fill_vertical" /> + android:gravity="fill_vertical" + android:text="Topic" + android:textColor="?attr/colorAccent" /> <TextView android:id="@+id/topic" @@ -64,20 +63,17 @@ android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:text="No Topic Set" - android:textStyle="italic" - android:textColor="?attr/colorForegroundSecondary" android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead" /> <android.support.v7.widget.AppCompatButton + android:id="@+id/edit_topic" + style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="right" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:id="@+id/edit_topic" - android:text="Edit Topic" - style="@style/Widget.AppCompat.Button.Colored" - android:layout_gravity="right" /> + android:text="Edit Topic" /> <View android:layout_width="match_parent" @@ -89,30 +85,30 @@ style="@style/TextAppearance.AppCompat.Button" android:layout_width="match_parent" android:layout_height="48dp" - android:textColor="?attr/colorAccent" - android:text="Channel Modes" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:gravity="fill_vertical" /> + android:gravity="fill_vertical" + android:text="Channel Modes" + android:textColor="?attr/colorAccent" /> <LinearLayout android:id="@+id/modes" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:paddingBottom="8dp" android:paddingLeft="8dp" - android:paddingRight="8dp" - android:paddingBottom="8dp" /> + android:paddingRight="8dp" /> </LinearLayout> </ScrollView> <ProgressBar + android:id="@+id/progressBar2" style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:id="@+id/progressBar2" android:layout_gravity="right" /> </LinearLayout> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 50c6366d1..6d6116907 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -20,19 +20,70 @@ ~ with this program. If not, see <http://www.gnu.org/licenses/>. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" + android:background="?attr/colorBackground" tools:context=".ui.chat.MainActivity"> - <include layout="@layout/widget_actionbar" /> - - <FrameLayout - android:id="@+id/content_host" + <LinearLayout android:layout_width="match_parent" - android:layout_height="match_parent" /> + android:layout_height="match_parent" + android:orientation="vertical"> + + <include layout="@layout/widget_actionbar" /> + + <FrameLayout + android:id="@+id/content_host" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </LinearLayout> + + <android.support.design.widget.NavigationView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="start" + android:background="?attr/colorBackground"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical"> + + <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <android.support.v7.widget.Toolbar + android:id="@+id/chatListToolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:theme="@style/AppTheme.AppBarOverlay" + app:popupTheme="@style/AppTheme.PopupOverlay"> + + <android.support.v7.widget.AppCompatSpinner + android:id="@+id/chatListSpinner" + android:layout_width="fill_parent" + android:layout_height="match_parent" /> + + </android.support.v7.widget.Toolbar> + + </android.support.design.widget.AppBarLayout> + + <android.support.v7.widget.RecyclerView + android:id="@+id/chatList" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </LinearLayout> + + </android.support.design.widget.NavigationView> -</LinearLayout> +</android.support.v4.widget.DrawerLayout> diff --git a/app/src/main/res/layout/fragment_chat.xml b/app/src/main/res/layout/fragment_chat.xml index a38ddea75..5816e09be 100644 --- a/app/src/main/res/layout/fragment_chat.xml +++ b/app/src/main/res/layout/fragment_chat.xml @@ -22,8 +22,8 @@ <com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/sliding_layout" android:layout_width="match_parent" android:layout_height="match_parent" @@ -32,7 +32,6 @@ app:umanoPanelHeight="?attr/actionBarSize" app:umanoScrollableView="@+id/chatline_scroller" app:umanoShadowHeight="4dp" - android:background="?attr/colorBackground" tools:showIn="@layout/activity_chat"> <android.support.v4.widget.SwipeRefreshLayout diff --git a/app/src/main/res/layout/fragment_loading.xml b/app/src/main/res/layout/fragment_loading.xml index 0e3d3cafe..17025c0e1 100644 --- a/app/src/main/res/layout/fragment_loading.xml +++ b/app/src/main/res/layout/fragment_loading.xml @@ -22,8 +22,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="?attr/colorBackground"> + android:layout_height="match_parent"> <LinearLayout android:layout_width="240dp" diff --git a/app/src/main/res/layout/widget_buffer.xml b/app/src/main/res/layout/widget_buffer.xml new file mode 100644 index 000000000..11744dd70 --- /dev/null +++ b/app/src/main/res/layout/widget_buffer.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ QuasselDroid - Quassel client for Android + ~ Copyright (C) 2016 Janne Koschinski + ~ Copyright (C) 2016 Ken Børge Viktil + ~ Copyright (C) 2016 Magnus Fjell + ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + ~ + ~ This program 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. + ~ + ~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/material_drawer_item_secondary" + android:clickable="true" + android:orientation="horizontal" + android:paddingEnd="@dimen/material_drawer_vertical_padding" + android:paddingLeft="@dimen/material_drawer_vertical_padding" + android:paddingRight="@dimen/material_drawer_vertical_padding" + android:paddingStart="@dimen/material_drawer_vertical_padding"> + + <ImageView + android:id="@+id/material_drawer_icon" + android:layout_width="@dimen/material_drawer_item_secondary_icon" + android:layout_height="@dimen/material_drawer_item_secondary" + android:layout_gravity="center_vertical" + android:paddingBottom="@dimen/material_drawer_item_secondary_icon_padding" + android:paddingEnd="@dimen/material_drawer_item_secondary_icon_padding_right" + android:paddingLeft="0dp" + android:paddingRight="@dimen/material_drawer_item_secondary_icon_padding_right" + android:paddingStart="0dp" + android:paddingTop="@dimen/material_drawer_item_secondary_icon_padding" /> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:gravity="center_vertical|start" + android:orientation="vertical"> + + <TextView + android:id="@+id/material_drawer_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="sans-serif-medium" + android:gravity="center_vertical|start" + android:lines="1" + android:singleLine="true" + android:textSize="@dimen/material_drawer_item_secondary_text" + tools:text="Some secondary text" /> + + <TextView + android:id="@+id/material_drawer_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="sans-serif" + android:gravity="center_vertical|start" + android:lines="1" + android:singleLine="true" + android:textSize="@dimen/material_drawer_item_secondary_description" + tools:text="Some drawer text" /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/material_drawer_badge_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:background="@drawable/badge" + android:gravity="center" + android:padding="6dp"> + + <TextView + android:id="@+id/material_drawer_badge" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:fontFamily="sans-serif" + android:gravity="center" + android:lines="1" + android:minWidth="20dp" + android:paddingLeft="1dp" + android:paddingRight="1dp" + android:singleLine="true" + android:textColor="@color/md_white_1000" + android:textSize="@dimen/material_drawer_item_secondary_text" + tools:text="99+" /> + + </LinearLayout> + +</LinearLayout> diff --git a/app/src/main/res/layout/widget_network.xml b/app/src/main/res/layout/widget_network.xml new file mode 100644 index 000000000..ab5ee3e78 --- /dev/null +++ b/app/src/main/res/layout/widget_network.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ QuasselDroid - Quassel client for Android + ~ Copyright (C) 2016 Janne Koschinski + ~ Copyright (C) 2016 Ken Børge Viktil + ~ Copyright (C) 2016 Magnus Fjell + ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org> + ~ + ~ This program 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. + ~ + ~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/material_drawer_item_primary" + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:orientation="horizontal" + android:paddingEnd="@dimen/material_drawer_vertical_padding" + android:paddingLeft="@dimen/material_drawer_vertical_padding" + android:paddingRight="@dimen/material_drawer_vertical_padding" + android:paddingStart="@dimen/material_drawer_vertical_padding"> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:gravity="center_vertical|start" + android:orientation="vertical"> + + <TextView + android:id="@+id/material_drawer_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="sans-serif-medium" + android:gravity="center_vertical|start" + android:lines="1" + android:singleLine="true" + android:textDirection="anyRtl" + android:textSize="@dimen/material_drawer_item_primary_text" + tools:text="Some drawer text" /> + + </LinearLayout> + +</LinearLayout> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86cf89e1d..e7d116012 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -73,4 +73,5 @@ <string name="statusConnected">Connected</string> <string name="statusWelcome">Welcome!</string> <string name="statusDisconnected">Connection lost</string> + <string name="no_topic_set">No Topic Set</string> </resources> -- GitLab