From 9d132430d41c3ed399e82f9d78b918a9239dcff6 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Sat, 27 Aug 2016 14:04:36 +0200 Subject: [PATCH] Fixed backlog gaps not being removed, added search view --- app/build.gradle | 11 ++++ .../libquassel/localtypes/BacklogFilter.java | 13 ++++- .../backlogstorage/BacklogStorage.java | 6 ++ .../backlogstorage/HybridBacklogStorage.java | 36 +++++++++++- .../backlogstorage/MemoryBacklogStorage.java | 22 +++++++ .../syncables/types/impl/BacklogManager.java | 6 +- .../quasseldroid_ng/ui/chat/MainActivity.java | 27 ++++++++- .../ui/chat/chatview/ChatMessageRenderer.java | 6 +- .../ui/chat/fragment/ChatFragment.java | 20 ++++++- .../ui/chat/util/SlidingPanelHandler.java | 57 ++----------------- .../quasseldroid_ng/ui/theme/ThemeUtil.java | 10 ++-- .../irc/format/IrcFormatDeserializer.java | 22 ++++++- app/src/main/res/layout/widget_slider.xml | 8 +-- app/src/main/res/menu/chat.xml | 11 +++- app/src/main/res/values/strings.xml | 3 + 15 files changed, 180 insertions(+), 78 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 7547f70f7..a2fd16b3e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -159,6 +159,8 @@ dependencies { compile "com.github.Raizlabs.DBFlow:dbflow-core:3.1.1" compile "com.github.Raizlabs.DBFlow:dbflow:3.1.1" + + // Appcompat compile 'com.android.support:appcompat-v7:24.0.0' compile 'com.android.support:design:24.0.0' compile 'com.android.support:support-v4:24.0.0' @@ -166,6 +168,15 @@ dependencies { compile 'com.android.support:preference-v14:24.0.0' compile 'com.android.support:cardview-v7:24.0.0' + // Reactive Libs + compile 'io.reactivex:rxandroid:1.2.1' + compile 'io.reactivex:rxjava:1.1.6' + compile 'com.jakewharton.rxbinding:rxbinding:0.4.0' + compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0' + compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.4.0' + compile 'com.jakewharton.rxbinding:rxbinding-design:0.4.0' + compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.4.0' + // Crashreports compile 'ch.acra:acra:4.9.0' 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 e251540c8..0281af62e 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java @@ -36,6 +36,7 @@ import de.kuschku.libquassel.client.Client; import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; +import de.kuschku.util.irc.IrcUserUtils; import de.kuschku.util.observables.callbacks.UICallback; import de.kuschku.util.observables.lists.ObservableComparableSortedList; @@ -52,6 +53,8 @@ public class BacklogFilter implements UICallback { @NonNull private final Set<Message.Type> filteredTypes = new HashSet<>(); + @Nullable + private CharSequence searchQuery; private final EventBus bus = new EventBus(); @Nullable private DateTime earliestMessage; @@ -96,7 +99,10 @@ public class BacklogFilter implements UICallback { private boolean filterItem(@NonNull Message message) { 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); + boolean ignored = client.ignoreListManager() != null && client.ignoreListManager().matches(message, network); + boolean filtered = filteredTypes.contains(message.type); + boolean isSearching = searchQuery != null && searchQuery.length() != 0; + return ignored || filtered || (isSearching && !message.content.contains(searchQuery)); } public void addFilter(Message.Type type) { @@ -114,6 +120,11 @@ public class BacklogFilter implements UICallback { bus.post(new UpdateRemoveEvent()); } + public void setQuery(CharSequence query) { + searchQuery = query; + update(); + } + public void onEventAsync(UpdateAddEvent event) { for (Message message : unfiltered) { if (!filterItem(message)) { diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java index 95ef6c34e..1df4329f9 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java @@ -24,6 +24,8 @@ package de.kuschku.libquassel.localtypes.backlogstorage; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import java.util.List; + import de.kuschku.libquassel.client.Client; import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.message.Message; @@ -43,8 +45,12 @@ public interface BacklogStorage { void insertMessages(@IntRange(from = 0) int bufferId, Message... messages); + void insertMessages(@IntRange(from = 0) int bufferId, List<Message> messages); + void insertMessages(Message... messages); + void insertMessages(List<Message> messages); + void setClient(Client client); void markBufferUnused(@IntRange(from = 0) int bufferid); diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/HybridBacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/HybridBacklogStorage.java index 0127826da..f702dcb0d 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/HybridBacklogStorage.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/HybridBacklogStorage.java @@ -23,6 +23,7 @@ package de.kuschku.libquassel.localtypes.backlogstorage; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import android.util.Log; import android.util.SparseArray; import com.raizlabs.android.dbflow.config.FlowManager; @@ -99,6 +100,26 @@ public class HybridBacklogStorage implements BacklogStorage { }); } + @Override + public void insertMessages(@IntRange(from = 0) int bufferId, List<Message> messages) { + ensureExisting(bufferId); + FlowManager.getDatabase(ConnectedDatabase.class).executeTransaction(new ITransaction() { + @Override + public void execute(DatabaseWrapper databaseWrapper) { + for (Message message : messages) { + client.unbufferBuffer(message.bufferInfo); + synchronized (backlogs) { + if (backlogs.get(bufferId) != null) + backlogs.get(bufferId).add(message); + message.save(); + message.bufferInfo.save(); + } + updateLatest(message); + } + } + }); + } + public void updateLatest(@NonNull Message message) { if (message.id > getLatest(message.bufferInfo.id)) { latestMessage.put(message.bufferInfo.id, message.id); @@ -117,6 +138,18 @@ public class HybridBacklogStorage implements BacklogStorage { } } + @Override + public void insertMessages(List<Message> messages) { + for (Message message : messages) { + client.unbufferBuffer(message.bufferInfo); + synchronized (backlogs) { + if (backlogs.get(message.bufferInfo.id) != null) + backlogs.get(message.bufferInfo.id).add(message); + } + updateLatest(message); + } + } + public void setClient(Client client) { this.client = client; } @@ -134,7 +167,8 @@ public class HybridBacklogStorage implements BacklogStorage { @Override public void clear(@IntRange(from = 0) int bufferid) { - SQLite.delete().from(Message.class).where(Message_Table.bufferInfo_id.eq(bufferid)); + Log.w("libquassel", String.format("Backlog gap detected, clearing backlog for buffer %d", bufferid)); + SQLite.delete().from(Message.class).where(Message_Table.bufferInfo_id.eq(bufferid)).execute(); } private void ensureExisting(@IntRange(from = -1) int bufferId) { diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java index 462354cb5..fe0c2e4ba 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java @@ -25,6 +25,8 @@ import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.util.SparseArray; +import java.util.List; + import de.kuschku.libquassel.client.Client; import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.message.Message; @@ -80,6 +82,16 @@ public class MemoryBacklogStorage implements BacklogStorage { } } + @Override + public void insertMessages(@IntRange(from = 0) int bufferId, List<Message> messages) { + ensureExisting(bufferId); + for (Message message : messages) { + client.unbufferBuffer(message.bufferInfo); + backlogs.get(bufferId).add(message); + updateLatest(message); + } + } + public void updateLatest(@NonNull Message message) { if (message.id > getLatest(message.bufferInfo.id)) { latestMessage.put(message.bufferInfo.id, message.id); @@ -96,6 +108,16 @@ public class MemoryBacklogStorage implements BacklogStorage { } } + @Override + public void insertMessages(List<Message> messages) { + for (Message message : messages) { + ensureExisting(message.bufferInfo.id); + client.unbufferBuffer(message.bufferInfo); + backlogs.get(message.bufferInfo.id).add(message); + updateLatest(message); + } + } + public void setClient(Client client) { this.client = client; } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java index 62c97c1f0..218528838 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java @@ -96,12 +96,10 @@ public class BacklogManager extends ABacklogManager<BacklogManager> { public void _receiveBacklog(int id, int first, int last, int limit, int additional, @NonNull List<Message> messages) { assertNotNull(provider); - Log.d("DEBUG", "Received " + messages.size() + " messages out of a max of " + limit); - Message lastMessageForBuffer = SQLite.select().from(Message.class).where(Message_Table.bufferInfo_id.eq(id)).orderBy(Message_Table.id, false).limit(1).querySingle(); - if (lastMessageForBuffer != null && messages.get(0).id > lastMessageForBuffer.id) + if (lastMessageForBuffer != null && messages.size() > 0 && messages.get(0).id > lastMessageForBuffer.id) storage.clear(id); - storage.insertMessages(id, messages.toArray(new Message[messages.size()])); + storage.insertMessages(id, messages); if (messages.size() > 0 && !client.bufferManager().exists(messages.get(0).bufferInfo)) client.bufferManager().createBuffer(messages.get(0).bufferInfo); provider.sendEvent(new BacklogReceivedEvent(id)); 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 9a8cf337a..7174af59d 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 @@ -21,6 +21,7 @@ package de.kuschku.quasseldroid_ng.ui.chat; +import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; @@ -28,6 +29,7 @@ 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.view.MenuItemCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.AppCompatEditText; @@ -35,6 +37,7 @@ 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.SearchView; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; @@ -43,10 +46,12 @@ import android.widget.AdapterView; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; +import com.jakewharton.rxbinding.support.v7.widget.RxSearchView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; import butterknife.Bind; import butterknife.ButterKnife; @@ -76,6 +81,8 @@ import de.kuschku.util.accounts.AccountManager; import de.kuschku.util.certificates.CertificateUtils; import de.kuschku.util.certificates.SQLiteCertificateManager; import de.kuschku.util.servicebound.BoundActivity; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; import static de.kuschku.util.AndroidAssert.assertNotNull; @@ -112,6 +119,7 @@ public class MainActivity extends BoundActivity { private ToolbarWrapper toolbarWrapper; private BufferViewConfigAdapter chatListAdapter; + private Fragment currentFragment; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -178,6 +186,7 @@ public class MainActivity extends BoundActivity { private void replaceFragment(Fragment fragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + this.currentFragment = fragment; transaction.replace(R.id.content_host, fragment); transaction.commit(); } @@ -201,6 +210,16 @@ public class MainActivity extends BoundActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.chat, menu); + final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search)); + SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE); + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + RxSearchView.queryTextChanges(searchView) + .debounce(400, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(charSequence -> { + if (context.client() != null) + context.client().backlogStorage().getFilter(context.client().backlogManager().open()).setQuery(charSequence); + }); return super.onCreateOptionsMenu(menu); } @@ -299,7 +318,6 @@ public class MainActivity extends BoundActivity { } } - /* private void updateBufferViewConfigs() { assertNotNull(context.client().bufferViewManager()); @@ -321,6 +339,13 @@ public class MainActivity extends BoundActivity { } */ + @Override + public void onBackPressed() { + if (!(currentFragment instanceof ChatFragment) || ((ChatFragment) currentFragment).onBackPressed()) { + super.onBackPressed(); + } + } + @Override protected void onConnectToThread(@Nullable ClientBackgroundThread thread) { super.onConnectToThread(thread); diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java index ffddc7856..683444a26 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java @@ -188,7 +188,7 @@ public class ChatMessageRenderer { private void onBindQuit(@NonNull MessageViewHolder holder, @NonNull Message message) { applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight); - if (message.content.isEmpty()) + if (message.content == null || message.content.isEmpty()) holder.content.setText(context.themeUtil().translations.formatQuit( formatNick(message.sender) )); @@ -205,12 +205,14 @@ public class ChatMessageRenderer { holder.content.setText(context.themeUtil().translations.formatKick( formatNick(message.sender), message.content.substring(0, message.content.indexOf(" ")), + getBufferName(message), message.content.substring(message.content.indexOf(" ") + 1) )); else holder.content.setText(context.themeUtil().translations.formatKick( formatNick(message.sender), - message.content + message.content, + getBufferName(message) )); } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java index 5fc78b2f3..ba5cfdbee 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java @@ -24,14 +24,13 @@ package de.kuschku.quasseldroid_ng.ui.chat.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.AbsListView; import com.sothree.slidinguppanel.SlidingUpPanelLayout; @@ -84,6 +83,7 @@ public class ChatFragment extends BoundFragment { messageAdapter = new MessageAdapter(getActivity(), context, new AutoScroller(messages)); messages.setAdapter(messageAdapter); + final int measuredHeight = messages.getMeasuredHeight(); messages.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { @@ -95,7 +95,12 @@ public class ChatFragment extends BoundFragment { backlogManager.requestMoreBacklog(client.backlogManager().open(), 20); loading = true; } - scrollDown.setVisibility(recyclerView.canScrollVertically(1) ? View.VISIBLE : View.GONE); + boolean canScrollDown = recyclerView.canScrollVertically(1); + boolean isScrollingDown = dy > 0; + int scrollOffsetFromBottom = recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollOffset() - measuredHeight; + boolean isMoreThanOneScreenFromBottom = scrollOffsetFromBottom > measuredHeight; + boolean smartVisibility = scrollDown.getVisibility() == View.VISIBLE || isMoreThanOneScreenFromBottom; + scrollDown.setVisibility((canScrollDown && isScrollingDown && smartVisibility) ? View.VISIBLE : View.GONE); } }); @@ -143,4 +148,13 @@ public class ChatFragment extends BoundFragment { loading = false; } } + + public boolean onBackPressed() { + if (sliderMain.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + sliderMain.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); + return false; + } else { + return true; + } + } } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/SlidingPanelHandler.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/SlidingPanelHandler.java index 5735b9a91..ef37d40da 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/SlidingPanelHandler.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/util/SlidingPanelHandler.java @@ -22,9 +22,6 @@ package de.kuschku.quasseldroid_ng.ui.chat.util; import android.app.Activity; -import android.graphics.Color; -import android.support.annotation.ColorInt; -import android.support.annotation.FloatRange; import android.support.v7.widget.ActionMenuView; import android.support.v7.widget.AppCompatEditText; import android.support.v7.widget.AppCompatImageButton; @@ -79,6 +76,7 @@ public class SlidingPanelHandler { AppCompatEditText chatline; @Bind(R.id.send) AppCompatImageButton send; + private ItemAdapter<IItem> previousMessages; public SlidingPanelHandler(Activity activity, SlidingUpPanelLayout slidingLayout, AppContext context) { this.slidingLayout = slidingLayout; @@ -152,42 +150,12 @@ public class SlidingPanelHandler { chatline.setSelection(selectionStart, selectionEnd); } - private int combineColors(@ColorInt int colora, @ColorInt int colorb, @FloatRange(from = 0.0, to = 1.0) float offset) { - float invOffset = 1 - offset; - - double alphaA = Math.pow(Color.alpha(colora), 2); - double alphaB = Math.pow(Color.alpha(colorb), 2); - - double redA = Math.pow(Color.red(colora), 2); - double redB = Math.pow(Color.red(colorb), 2); - - double greenA = Math.pow(Color.green(colora), 2); - double greenB = Math.pow(Color.green(colorb), 2); - - double blueA = Math.pow(Color.blue(colora), 2); - double blueB = Math.pow(Color.blue(colorb), 2); - - return Color.argb( - (int) Math.sqrt(alphaA * invOffset + alphaB * offset), - (int) Math.sqrt(redA * invOffset + redB * offset), - (int) Math.sqrt(greenA * invOffset + greenB * offset), - (int) Math.sqrt(blueA * invOffset + blueB * offset) - ); - } - private void bindListener() { slidingLayout.setAntiDragView(R.id.card_panel); slidingLayout.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() { @Override public void onPanelSlide(View panel, float slideOffset) { - /* - slidingLayoutHistory.setBackgroundColor(combineColors( - context.themeUtil().res.colorBackgroundCard, - context.themeUtil().res.colorBackground, - slideOffset - )); - */ } @Override @@ -237,31 +205,14 @@ public class SlidingPanelHandler { context.client().sendInput(buffer.getInfo(), text); chatline.setText(""); chatline.requestFocus(); + previousMessages.add(new PrimaryDrawerItem().withName(text)); } } private void setupHistoryFakeData() { FastAdapter<IItem> fastAdapter = new FastAdapter<>(); - ItemAdapter<IItem> itemAdapter = new ItemAdapter<>(); - itemAdapter.wrap(fastAdapter); - itemAdapter.add( - new PrimaryDrawerItem().withName("Entry #1"), - new PrimaryDrawerItem().withName("Entry #2"), - new PrimaryDrawerItem().withName("Entry #3"), - new PrimaryDrawerItem().withName("Entry #4"), - new PrimaryDrawerItem().withName("Entry #5"), - new PrimaryDrawerItem().withName("Entry #6"), - new PrimaryDrawerItem().withName("Entry #7"), - new PrimaryDrawerItem().withName("Entry #8"), - new PrimaryDrawerItem().withName("Entry #9"), - new PrimaryDrawerItem().withName("Entry #10"), - new PrimaryDrawerItem().withName("Entry #11"), - new PrimaryDrawerItem().withName("Entry #12"), - new PrimaryDrawerItem().withName("Entry #13"), - new PrimaryDrawerItem().withName("Entry #14"), - new PrimaryDrawerItem().withName("Entry #15"), - new PrimaryDrawerItem().withName("Entry #16") - ); + previousMessages = new ItemAdapter<>(); + previousMessages.wrap(fastAdapter); msgHistory.setAdapter(fastAdapter); msgHistory.setLayoutManager(new LinearLayoutManager(activity)); msgHistory.setItemAnimator(new DefaultItemAnimator()); 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 481985a31..818c1a9d6 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 @@ -663,15 +663,15 @@ public class ThemeUtil { } @NonNull - public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked) { - return SpanFormatter.format(messageKick, user, kicked); + public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked, @NonNull CharSequence channel) { + return SpanFormatter.format(messageKick, user, kicked, channel); } @NonNull - public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked, @Nullable CharSequence reason) { - if (reason == null || reason.length() == 0) return formatKick(user, kicked); + public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked, @Nullable CharSequence reason, @NonNull CharSequence channel) { + if (reason == null || reason.length() == 0) return formatKick(user, kicked, channel); - return SpanFormatter.format(messageKickExtra, user, kicked, reason); + return SpanFormatter.format(messageKickExtra, user, kicked, reason, channel); } @NonNull diff --git a/app/src/main/java/de/kuschku/util/irc/format/IrcFormatDeserializer.java b/app/src/main/java/de/kuschku/util/irc/format/IrcFormatDeserializer.java index 3221e2171..9c57fca69 100644 --- a/app/src/main/java/de/kuschku/util/irc/format/IrcFormatDeserializer.java +++ b/app/src/main/java/de/kuschku/util/irc/format/IrcFormatDeserializer.java @@ -122,10 +122,14 @@ public class IrcFormatDeserializer { boolean colorize = context.settings().preferenceColors.get(); // Iterating over every character + int normalCount = 0; for (int i = 0; i < str.length(); i++) { char character = str.charAt(i); switch (character) { case CODE_BOLD: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + // If there is an element on stack with the same code, close it if (bold != null) { if (colorize) bold.apply(plainText, plainText.length()); @@ -139,6 +143,9 @@ public class IrcFormatDeserializer { } break; case CODE_ITALIC: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + // If there is an element on stack with the same code, close it if (italic != null) { if (colorize) italic.apply(plainText, plainText.length()); @@ -152,6 +159,9 @@ public class IrcFormatDeserializer { } break; case CODE_UNDERLINE: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + // If there is an element on stack with the same code, close it if (underline != null) { if (colorize) underline.apply(plainText, plainText.length()); @@ -165,6 +175,9 @@ public class IrcFormatDeserializer { } break; case CODE_COLOR: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + int foregroundStart = i + 1; int foregroundEnd = findEndOfNumber(str, foregroundStart); // If we have a foreground element @@ -200,6 +213,9 @@ public class IrcFormatDeserializer { } break; case CODE_SWAP: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + // If we have a color tag before, apply it, and create a new one with swapped colors if (color != null) { if (colorize) color.apply(plainText, plainText.length()); @@ -208,6 +224,9 @@ public class IrcFormatDeserializer { } break; case CODE_RESET: { + plainText.append(str.substring(i - normalCount, i)); + normalCount = 0; + // End all formatting tags if (bold != null) { if (colorize) bold.apply(plainText, plainText.length()); @@ -229,7 +248,7 @@ public class IrcFormatDeserializer { break; default: { // Just append it, if it’s not special - plainText.append(character); + normalCount++; } } } @@ -247,6 +266,7 @@ public class IrcFormatDeserializer { if (color != null) { if (colorize) color.apply(plainText, plainText.length()); } + plainText.append(str.substring(str.length() - normalCount, str.length())); return plainText; } diff --git a/app/src/main/res/layout/widget_slider.xml b/app/src/main/res/layout/widget_slider.xml index 9d4a0fbb5..812fa9d2d 100644 --- a/app/src/main/res/layout/widget_slider.xml +++ b/app/src/main/res/layout/widget_slider.xml @@ -43,12 +43,12 @@ <FrameLayout android:id="@+id/card_panel" android:layout_width="fill_parent" - android:layout_height="wrap_content"> + android:layout_height="fill_parent"> <android.support.v7.widget.CardView style="?attr/cardStyle" android:layout_width="fill_parent" - android:layout_height="wrap_content" + android:layout_height="fill_parent" android:layout_marginBottom="16.0dip" android:layout_marginLeft="16.0dip" android:layout_marginRight="16.0dip" @@ -57,7 +57,7 @@ <LinearLayout android:layout_width="fill_parent" - android:layout_height="wrap_content" + android:layout_height="fill_parent" android:orientation="vertical"> <TextView @@ -73,7 +73,7 @@ <android.support.v7.widget.RecyclerView android:id="@+id/msg_history" android:layout_width="fill_parent" - android:layout_height="wrap_content" /> + android:layout_height="fill_parent" /> </LinearLayout> </android.support.v7.widget.CardView> </FrameLayout> diff --git a/app/src/main/res/menu/chat.xml b/app/src/main/res/menu/chat.xml index 734041b96..7381ab764 100644 --- a/app/src/main/res/menu/chat.xml +++ b/app/src/main/res/menu/chat.xml @@ -26,13 +26,18 @@ android:id="@+id/action_hide_events" android:icon="?attr/iconFilter" android:title="@string/labelHideEvents" - app:showAsAction="ifRoom" /> + app:showAsAction="never" /> + <item + android:id="@+id/action_search" + android:title="@string/label_search" + app:showAsAction="never|collapseActionView" + app:actionViewClass="android.support.v7.widget.SearchView" /> <item android:id="@+id/action_settings" - android:title="Settings" + android:title="@string/label_settings" app:showAsAction="never" /> <item android:id="@+id/action_reauth" - android:title="Disconnect" + android:title="@string/label_disconnect" app:showAsAction="never" /> </menu> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d94f0e3a0..ae9968bb3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -81,4 +81,7 @@ <string name="statusWelcome">Welcome!</string> <string name="statusDisconnected">Connection lost</string> <string name="notification_report_crash">Reporting Crashes</string> + <string name="label_settings">Settings</string> + <string name="label_search">Find in Buffer</string> + <string name="label_disconnect">Disconnect</string> </resources> -- GitLab