From d65bf005539ab1ad752e9938dbf71c97af9f265f Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Thu, 22 Feb 2018 02:14:14 +0100 Subject: [PATCH] Allow hiding message types --- app/build.gradle.kts | 1 + app/src/main/AndroidManifest.xml | 4 +- .../persistence/AccountDatabase.kt | 1 - .../persistence/QuasselBacklogStorage.kt | 5 +- .../persistence/QuasselDatabase.kt | 71 +++++++++++++--- .../quasseldroid_ng/ui/chat/ChatActivity.kt | 68 ++++++++++++++-- .../ui/chat/buffers/BufferListAdapter.kt | 50 ++++++------ .../chat/buffers/BufferViewConfigFragment.kt | 49 ++++++++--- .../ui/chat/messages/MessageListFragment.kt | 23 +++--- .../ui/viewmodel/QuasselViewModel.kt | 32 ++++---- .../util/service/ServiceBoundActivity.kt | 10 ++- .../util/service/ServiceBoundFragment.kt | 9 ++- app/src/main/res/menu/activity_main.xml | 9 ++- app/src/main/res/menu/setup_edit_account.xml | 4 +- app/src/main/res/values/strings.xml | 34 +++----- app/src/main/res/values/strings_messages.xml | 36 +++++++++ ...references.xml => strings_preferences.xml} | 2 +- app/src/main/res/values/themes_quassel.xml | 4 +- .../java/de/kuschku/libquassel/util/Flag.kt | 64 +++++++++------ .../de/kuschku/libquassel/util/LongFlag.kt | 81 ++++++++++--------- .../de/kuschku/libquassel/util/ShortFlag.kt | 73 +++++++++-------- 21 files changed, 412 insertions(+), 218 deletions(-) create mode 100644 app/src/main/res/values/strings_messages.xml rename app/src/main/res/values/{preferences.xml => strings_preferences.xml} (98%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 16103cc43..46b14cc6d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -139,6 +139,7 @@ dependencies { // UI implementation("me.zhanghai.android.materialprogressbar", "library", "1.4.2") + implementation("com.afollestad.material-dialogs", "core", "0.9.6.0") // Quality Assurance implementation(project(":malheur")) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b1135242e..cbd8970d0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,7 +31,7 @@ <activity android:name=".ui.settings.SettingsActivity" android:exported="false" - android:label="@string/app_name" + android:label="@string/label_settings" android:parentActivityName=".ui.chat.ChatActivity" android:windowSoftInputMode="adjustResize" /> <activity @@ -51,7 +51,7 @@ android:name=".service.QuasselService" android:description="@string/connection_service_description" android:exported="false" - android:label="@string/connection_service" /> + android:label="@string/connection_service_title" /> </application> </manifest> diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/AccountDatabase.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/AccountDatabase.kt index ebe1e6100..3be55470e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/AccountDatabase.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/AccountDatabase.kt @@ -43,7 +43,6 @@ abstract class AccountDatabase : RoomDatabase() { object Creator { private var database: AccountDatabase? = null - private set // For Singleton instantiation private val LOCK = Any() diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselBacklogStorage.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselBacklogStorage.kt index a0134e299..f3eb2a29a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselBacklogStorage.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselBacklogStorage.kt @@ -5,8 +5,9 @@ import de.kuschku.libquassel.protocol.Message import de.kuschku.libquassel.session.BacklogStorage class QuasselBacklogStorage(private val db: QuasselDatabase) : BacklogStorage { - override fun storeMessages(vararg messages: Message, initialLoad: Boolean) - = storeMessages(messages.asIterable(), initialLoad) + override fun storeMessages(vararg messages: Message, initialLoad: Boolean) = storeMessages( + messages.asIterable(), initialLoad + ) override fun storeMessages(messages: Iterable<Message>, initialLoad: Boolean) { if (initialLoad) diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt index 1c9637abe..5d7d0746a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt @@ -1,18 +1,24 @@ package de.kuschku.quasseldroid_ng.persistence +import android.arch.lifecycle.LiveData import android.arch.paging.DataSource +import android.arch.persistence.db.SupportSQLiteDatabase import android.arch.persistence.room.* +import android.arch.persistence.room.migration.Migration import android.content.Context import android.support.annotation.IntRange import android.support.v7.recyclerview.extensions.DiffCallback import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Type +import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase.DatabaseMessage +import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase.Filtered import org.threeten.bp.Instant -@Database(entities = [(QuasselDatabase.DatabaseMessage::class)], version = 2) -@TypeConverters(QuasselDatabase.DatabaseMessage.MessageTypeConverters::class) +@Database(entities = [DatabaseMessage::class, Filtered::class], version = 3) +@TypeConverters(DatabaseMessage.MessageTypeConverters::class) abstract class QuasselDatabase : RoomDatabase() { abstract fun message(): MessageDao + abstract fun filtered(): FilteredDao @Entity(tableName = "message") data class DatabaseMessage( @@ -43,12 +49,10 @@ abstract class QuasselDatabase : RoomDatabase() { object MessageDiffCallback : DiffCallback<DatabaseMessage>() { override fun areContentsTheSame(oldItem: QuasselDatabase.DatabaseMessage, - newItem: QuasselDatabase.DatabaseMessage) - = oldItem == newItem + newItem: QuasselDatabase.DatabaseMessage) = oldItem == newItem override fun areItemsTheSame(oldItem: QuasselDatabase.DatabaseMessage, - newItem: QuasselDatabase.DatabaseMessage) - = oldItem.messageId == newItem.messageId + newItem: QuasselDatabase.DatabaseMessage) = oldItem.messageId == newItem.messageId } } @@ -60,8 +64,10 @@ abstract class QuasselDatabase : RoomDatabase() { @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId ASC") fun findByBufferId(bufferId: Int): List<DatabaseMessage> - @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId DESC") - fun findByBufferIdPaged(bufferId: Int): DataSource.Factory<Int, DatabaseMessage> + @Query( + "SELECT * FROM message WHERE bufferId = :bufferId AND type & ~ :type > 0 ORDER BY messageId DESC" + ) + fun findByBufferIdPaged(bufferId: Int, type: Int): DataSource.Factory<Int, DatabaseMessage> @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId DESC LIMIT 1") fun findLastByBufferId(bufferId: Int): DatabaseMessage? @@ -90,6 +96,41 @@ abstract class QuasselDatabase : RoomDatabase() { fun clearMessages(@IntRange(from = 0) bufferId: Int, first: Int, last: Int) } + @Entity(tableName = "filtered", primaryKeys = ["accountId", "bufferId"]) + data class Filtered( + var accountId: Long, + var bufferId: Int, + var filtered: Int + ) + + @Dao + interface FilteredDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun replace(vararg entities: Filtered) + + @Query( + "SELECT filtered FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId UNION SELECT 0 as filtered ORDER BY filtered DESC LIMIT 1" + ) + fun get(accountId: Long, bufferId: Int): Int? + + @Query( + "SELECT filtered FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId UNION SELECT 0 as filtered ORDER BY filtered DESC LIMIT 1" + ) + fun listen(accountId: Long, bufferId: Int): LiveData<Int> + + @Query("SELECT * FROM filtered WHERE accountId = :accountId") + fun listen(accountId: Long): LiveData<List<Filtered>> + + @Query("DELETE FROM filtered") + fun clear() + + @Query("DELETE FROM filtered WHERE accountId = :accountId") + fun clear(accountId: Long) + + @Query("DELETE FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId") + fun clear(accountId: Long, bufferId: Int) + } + object Creator { private var database: QuasselDatabase? = null @@ -103,6 +144,14 @@ abstract class QuasselDatabase : RoomDatabase() { database = Room.databaseBuilder( context.applicationContext, QuasselDatabase::class.java, DATABASE_NAME + ).addMigrations( + object : Migration(2, 3) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + "CREATE TABLE filtered(bufferId INTEGER, accountId INTEGER, filtered INTEGER, PRIMARY KEY(accountId, bufferId));" + ) + } + } ).build() } } @@ -116,7 +165,9 @@ abstract class QuasselDatabase : RoomDatabase() { } } -fun QuasselDatabase.MessageDao.clearMessages(@IntRange(from = 0) - bufferId: Int, idRange: kotlin.ranges.IntRange) { +fun QuasselDatabase.MessageDao.clearMessages( + @IntRange(from = 0) bufferId: Int, + idRange: kotlin.ranges.IntRange +) { this.clearMessages(bufferId, idRange.first, idRange.last) } \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt index 0f7582815..471a9054e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt @@ -17,8 +17,13 @@ import android.widget.Button import android.widget.EditText import butterknife.BindView import butterknife.ButterKnife +import com.afollestad.materialdialogs.MaterialDialog +import de.kuschku.libquassel.protocol.Message +import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.session.ConnectionState import de.kuschku.libquassel.session.SocketAddress +import de.kuschku.libquassel.util.and +import de.kuschku.libquassel.util.or import de.kuschku.quasseldroid_ng.Keys import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.persistence.AccountDatabase @@ -84,8 +89,8 @@ class ChatActivity : ServiceBoundActivity() { drawerToggle = ActionBarDrawerToggle( this, drawerLayout, - R.string.drawer_open, - R.string.drawer_close + R.string.label_drawer_open, + R.string.label_drawer_close ) drawerToggle.syncState() @@ -94,8 +99,6 @@ class ChatActivity : ServiceBoundActivity() { if (backendValue != null) { val database = AccountDatabase.Creator.init(this) handler.post { - val accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) - ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 if (accountId == -1L) { setResult(Activity.RESULT_OK) finish() @@ -179,10 +182,61 @@ class ChatActivity : ServiceBoundActivity() { } override fun onOptionsItemSelected(item: MenuItem?) = when (item?.itemId) { - android.R.id.home -> { + android.R.id.home -> { drawerToggle.onOptionsItemSelected(item) } - R.id.clear -> { + + R.id.filter_messages -> { + handler.post { + val buffer = viewModel.getBuffer().value + if (buffer != null) { + val filtered = Message_Type.of(database.filtered().get(accountId, buffer) ?: 0) + val flags = intArrayOf( + Message.MessageType.Join.bit or Message.MessageType.NetsplitJoin.bit, + Message.MessageType.Part.bit, + Message.MessageType.Quit.bit or Message.MessageType.NetsplitQuit.bit, + Message.MessageType.Nick.bit, + Message.MessageType.Mode.bit, + Message.MessageType.Topic.bit + ) + val selectedIndices = flags.withIndex().mapNotNull { (index, flag) -> + if ((filtered and flag).isNotEmpty()) { + index + } else { + null + } + }.toTypedArray() + + runOnUiThread { + MaterialDialog.Builder(this) + .title(R.string.label_filter_messages) + .items(R.array.message_filter_types) + .itemsIds(flags) + .itemsCallbackMultiChoice(selectedIndices, { _, _, _ -> false }) + .positiveText(R.string.label_select_multiple) + .negativeText(R.string.label_cancel) + .onPositive { dialog, _ -> + val selected = dialog.selectedIndices ?: emptyArray() + handler.post { + val newlyFiltered = selected + .map { flags[it] } + .fold(Message_Type.of()) { acc, i -> acc or i } + + database.filtered().replace( + QuasselDatabase.Filtered(accountId, buffer, newlyFiltered.value) + ) + } + }.negativeColorAttr(R.attr.colorTextPrimary) + .backgroundColorAttr(R.attr.colorBackgroundCard) + .contentColorAttr(R.attr.colorTextPrimary) + .build() + .show() + } + } + } + true + } + R.id.clear -> { handler.post { viewModel.sessionManager { manager -> viewModel.getBuffer().let { buffer -> @@ -197,7 +251,7 @@ class ChatActivity : ServiceBoundActivity() { } true } - R.id.settings -> { + R.id.settings -> { startActivity(Intent(applicationContext, SettingsActivity::class.java)) true } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt index b6c653436..bf4dc0cc0 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt @@ -15,10 +15,7 @@ import android.widget.ImageView import android.widget.TextView import butterknife.BindView import butterknife.ButterKnife -import de.kuschku.libquassel.protocol.BufferId -import de.kuschku.libquassel.protocol.Buffer_Activity -import de.kuschku.libquassel.protocol.Buffer_Type -import de.kuschku.libquassel.protocol.NetworkId +import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.hasFlag @@ -143,8 +140,9 @@ class BufferListAdapter( val network: INetwork.NetworkInfo, val bufferStatus: BufferStatus, val description: CharSequence, - val activity: Buffer_Activity, - val highlights: Int = 0 + val activity: Message_Types, + val highlights: Int = 0, + val bufferActivity: Buffer_Activities = Buffer_Activity.of(Buffer_Activity.NoActivity) ) data class BufferState( @@ -204,11 +202,11 @@ class BufferListAdapter( networkId = props.info.networkId name.setTextColor( - when (props.activity) { - Buffer_Activity.NoActivity -> none - Buffer_Activity.OtherActivity -> activity - Buffer_Activity.NewMessage -> message - Buffer_Activity.Highlight -> highlight + when { + props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight + props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message + props.bufferActivity.hasFlag(Buffer_Activity.OtherActivity) -> activity + else -> none } ) @@ -276,11 +274,11 @@ class BufferListAdapter( description.text = props.description name.setTextColor( - when (props.activity) { - Buffer_Activity.NoActivity -> none - Buffer_Activity.OtherActivity -> activity - Buffer_Activity.NewMessage -> message - Buffer_Activity.Highlight -> highlight + when { + props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight + props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message + props.bufferActivity.hasFlag(Buffer_Activity.OtherActivity) -> activity + else -> none } ) @@ -351,11 +349,11 @@ class BufferListAdapter( description.text = props.description name.setTextColor( - when (props.activity) { - Buffer_Activity.NoActivity -> none - Buffer_Activity.OtherActivity -> activity - Buffer_Activity.NewMessage -> message - Buffer_Activity.Highlight -> highlight + when { + props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight + props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message + props.bufferActivity.hasFlag(Buffer_Activity.OtherActivity) -> activity + else -> none } ) @@ -429,11 +427,11 @@ class BufferListAdapter( description.text = props.description name.setTextColor( - when (props.activity) { - Buffer_Activity.NoActivity -> none - Buffer_Activity.OtherActivity -> activity - Buffer_Activity.NewMessage -> message - Buffer_Activity.Highlight -> highlight + when { + props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight + props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message + props.bufferActivity.hasFlag(Buffer_Activity.OtherActivity) -> activity + else -> none } ) diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt index d2e8bfb0d..7feb5e9e1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt @@ -10,12 +10,19 @@ import android.widget.AdapterView import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.protocol.BufferId +import de.kuschku.libquassel.protocol.Buffer_Activity +import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.protocol.Message_Type +import de.kuschku.libquassel.util.hasFlag +import de.kuschku.libquassel.util.minus import de.kuschku.quasseldroid_ng.R +import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase import de.kuschku.quasseldroid_ng.ui.settings.Settings import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.helper.map +import de.kuschku.quasseldroid_ng.util.helper.zip import de.kuschku.quasseldroid_ng.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment @@ -32,6 +39,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { lateinit var chatList: RecyclerView private lateinit var viewModel: QuasselViewModel + private lateinit var database: QuasselDatabase private var ircFormatDeserializer: IrcFormatDeserializer? = null private lateinit var appearanceSettings: AppearanceSettings @@ -41,6 +49,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { super.onCreate(savedInstanceState) viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java] + database = QuasselDatabase.Creator.init(activity!!) appearanceSettings = Settings.appearance(activity!!) if (ircFormatDeserializer == null) { @@ -53,9 +62,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { val view = inflater.inflate(R.layout.fragment_chat_list, container, false) ButterKnife.bind(this, view) - val adapter = BufferViewConfigAdapter( - this, viewModel.bufferViewConfigs - ) + val adapter = BufferViewConfigAdapter(this, viewModel.bufferViewConfigs) chatListSpinner.adapter = adapter chatListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { @@ -70,14 +77,34 @@ class BufferViewConfigFragment : ServiceBoundFragment() { chatList.adapter = BufferListAdapter( this, - viewModel.bufferList.map { - it.map { - it.copy( - description = ircFormatDeserializer?.formatString( - it.description.toString(), appearanceSettings.colorizeMirc - ) ?: it.description - ) - } + viewModel.bufferList.zip(database.filtered().listen(accountId)).map { + val (list, activityList) = it + val activities = activityList.map { it.bufferId to it.filtered }.toMap() + list + ?.map { + val activity = it.activity - (activities[it.info.bufferId] ?: 0) + it.bufferActivity to it.copy( + description = ircFormatDeserializer?.formatString( + it.description.toString(), appearanceSettings.colorizeMirc + ) ?: it.description, + activity = activity, + bufferActivity = Buffer_Activity.of( + when { + it.highlights > 0 -> Buffer_Activity.Highlight + activity.hasFlag(Message_Type.Plain) || + activity.hasFlag(Message_Type.Notice) || + activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage + activity.isNotEmpty() -> Buffer_Activity.OtherActivity + else -> Buffer_Activity.NoActivity + } + ) + ) + }?.filter { (minimumActivity, props) -> + minimumActivity.toInt() <= props.bufferActivity.toInt() || + props.info.type.hasFlag(Buffer_Type.StatusBuffer) + }?.map { (_, props) -> + props + } }, handlerThread::post, activity!!::runOnUiThread, diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt index 1b5a92978..f3a923a63 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt @@ -52,7 +52,6 @@ class MessageListFragment : ServiceBoundFragment() { super.onCreate(savedInstanceState) viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java] appearanceSettings = Settings.appearance(activity!!) - setHasOptionsMenu(true) } private val boundaryCallback = object : @@ -87,16 +86,18 @@ class MessageListFragment : ServiceBoundFragment() { ) database = QuasselDatabase.Creator.init(context!!.applicationContext) - val data = viewModel.getBuffer().switchMapNotNull { - LivePagedListBuilder( - database.message().findByBufferIdPaged(it), - PagedList.Config.Builder() - .setPageSize(backlogSettings.dynamicAmount) - .setPrefetchDistance(backlogSettings.dynamicAmount) - .setInitialLoadSizeHint(backlogSettings.dynamicAmount) - .setEnablePlaceholders(true) - .build() - ).setBoundaryCallback(boundaryCallback).build() + val data = viewModel.getBuffer().switchMapNotNull { buffer -> + database.filtered().listen(accountId, buffer).switchMapNotNull { filtered -> + LivePagedListBuilder( + database.message().findByBufferIdPaged(buffer, filtered), + PagedList.Config.Builder() + .setPageSize(backlogSettings.dynamicAmount) + .setPrefetchDistance(backlogSettings.dynamicAmount) + .setInitialLoadSizeHint(backlogSettings.dynamicAmount) + .setEnablePlaceholders(true) + .build() + ).setBoundaryCallback(boundaryCallback).build() + } } handler.post { diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt index 5341b76c3..bd37272ed 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt @@ -4,9 +4,7 @@ import android.arch.lifecycle.LiveData import android.arch.lifecycle.MutableLiveData import android.arch.lifecycle.ViewModel import de.kuschku.libquassel.protocol.BufferId -import de.kuschku.libquassel.protocol.Buffer_Activity import de.kuschku.libquassel.protocol.Buffer_Type -import de.kuschku.libquassel.protocol.Message import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.IrcChannel @@ -232,16 +230,9 @@ class QuasselViewModel : ViewModel() { }.map { (info, network) -> bufferSyncer.liveActivity(info.bufferId).switchMap { activity -> bufferSyncer.liveHighlightCount(info.bufferId).map { highlights -> - when { - highlights > 0 -> Buffer_Activity.Highlight - activity.hasFlag(Message.MessageType.Plain) || - activity.hasFlag(Message.MessageType.Notice) || - activity.hasFlag(Message.MessageType.Action) -> Buffer_Activity.NewMessage - activity.isNotEmpty() -> Buffer_Activity.OtherActivity - else -> Buffer_Activity.NoActivity - } + activity to highlights } - }.switchMap { activity -> + }.switchMap { (activity, highlights) -> when (info.type.toInt()) { BufferInfo.Type.QueryBuffer.toInt() -> { network.liveIrcUser(info.bufferName).switchMap { user -> @@ -256,7 +247,9 @@ class QuasselViewModel : ViewModel() { else -> BufferListAdapter.BufferStatus.ONLINE }, description = realName, - activity = activity + activity = activity, + highlights = highlights, + bufferActivity = config.minimumActivity() ) } } @@ -275,7 +268,9 @@ class QuasselViewModel : ViewModel() { else -> BufferListAdapter.BufferStatus.ONLINE }, description = topic, - activity = activity + activity = activity, + highlights = highlights, + bufferActivity = config.minimumActivity() ) } } @@ -287,7 +282,9 @@ class QuasselViewModel : ViewModel() { network = network.networkInfo(), bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, description = "", - activity = activity + activity = activity, + highlights = highlights, + bufferActivity = config.minimumActivity() ) } } @@ -297,7 +294,9 @@ class QuasselViewModel : ViewModel() { network = network.networkInfo(), bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, description = "", - activity = activity + activity = activity, + highlights = highlights, + bufferActivity = config.minimumActivity() ) ) } @@ -309,9 +308,6 @@ class QuasselViewModel : ViewModel() { } ).map { list -> list.filter { - config.minimumActivity().value <= it.activity.bit || - it.info.type.hasFlag(Buffer_Type.StatusBuffer) - }.filter { (!config.hideInactiveBuffers()) || it.bufferStatus != BufferListAdapter.BufferStatus.OFFLINE || it.info.type.hasFlag(Buffer_Type.StatusBuffer) diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt index a64921334..ad471ecfc 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundActivity.kt @@ -1,11 +1,13 @@ package de.kuschku.quasseldroid_ng.util.service import android.arch.lifecycle.LiveData +import android.content.Context import android.os.Bundle import android.support.annotation.ColorRes import android.support.annotation.DrawableRes import android.support.v7.app.AppCompatActivity import de.kuschku.libquassel.session.Backend +import de.kuschku.quasseldroid_ng.Keys import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.ui.settings.Settings import de.kuschku.quasseldroid_ng.ui.settings.data.AppearanceSettings @@ -18,15 +20,19 @@ abstract class ServiceBoundActivity : AppCompatActivity() { protected val recentsHeaderColor: Int = R.color.colorPrimary private val connection = BackendServiceConnection() - val backend: LiveData<Backend?> + protected val backend: LiveData<Backend?> get() = connection.backend protected lateinit var appearanceSettings: AppearanceSettings + protected var accountId: Long = -1 override fun onCreate(savedInstanceState: Bundle?) { - connection.context = this + appearanceSettings = Settings.appearance(this) + accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) + ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 + setTheme(appearanceSettings.theme.style) super.onCreate(savedInstanceState) connection.start() diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundFragment.kt index 6d42d7227..c524cc583 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/service/ServiceBoundFragment.kt @@ -1,17 +1,24 @@ package de.kuschku.quasseldroid_ng.util.service import android.arch.lifecycle.LiveData +import android.content.Context import android.os.Bundle import android.support.v4.app.Fragment import de.kuschku.libquassel.session.Backend +import de.kuschku.quasseldroid_ng.Keys abstract class ServiceBoundFragment : Fragment() { private var connection = BackendServiceConnection() - val backend: LiveData<Backend?> + protected val backend: LiveData<Backend?> get() = connection.backend + protected var accountId: Long = -1 + override fun onCreate(savedInstanceState: Bundle?) { + accountId = context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) + ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 + connection.context = context super.onCreate(savedInstanceState) connection.start() diff --git a/app/src/main/res/menu/activity_main.xml b/app/src/main/res/menu/activity_main.xml index 3c59fa43c..1dd3df6f7 100644 --- a/app/src/main/res/menu/activity_main.xml +++ b/app/src/main/res/menu/activity_main.xml @@ -1,12 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/filter_messages" + android:title="@string/label_filter_messages" /> <item android:id="@+id/clear" - android:title="Clear Backlog" /> + android:title="@string/label_clear_backlog" /> <item android:id="@+id/settings" - android:title="Settings" /> + android:title="@string/label_settings" /> <item android:id="@+id/disconnect" - android:title="Disconnect" /> + android:title="@string/label_disconnect" /> </menu> diff --git a/app/src/main/res/menu/setup_edit_account.xml b/app/src/main/res/menu/setup_edit_account.xml index 6c17b9047..06155b5aa 100644 --- a/app/src/main/res/menu/setup_edit_account.xml +++ b/app/src/main/res/menu/setup_edit_account.xml @@ -3,12 +3,12 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/save" - android:title="Save" + android:title="@string/label_save" app:showAsAction="ifRoom" /> <item android:id="@+id/delete" android:icon="@drawable/ic_delete" - android:title="Delete" + android:title="@string/label_delete" app:iconTint="#fff" app:showAsAction="never" /> </menu> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5706a39f2..5012780a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,29 +1,17 @@ <resources> <string name="app_name">QuasselDroid</string> - <string name="connection_service">Connection Service</string> + <string name="connection_service_title">Connection Service</string> <string name="connection_service_description">Keeps a connection to your core to allow for notifications, and to transmit messages.</string> - <string name="crash_text">QD-NG has crashed</string> - <string name="drawer_open">Open</string> - <string name="drawer_close">Close</string> - - <string name="message_format_plain">%1$s%2$s: %3$s</string> - <string name="message_format_action">* %1$s%2$s %3$s</string> - <string name="message_format_notice">[%1$s%2$s] %3$s</string> - <string name="message_format_nick">%1$s%2$s is now known as %3$s%4$s</string> - <string name="message_format_mode">%1$s by %2$s%3$s</string> - <string name="message_format_join">%1$s%2$s joined</string> - <string name="message_format_part_1">%1$s%2$s left</string> - <string name="message_format_part_2">%1$s%2$s left: %3$s</string> - <string name="message_format_quit_1">%1$s%2$s quit</string> - <string name="message_format_quit_2">%1$s%2$s quit (%3$s)</string> - <plurals name="message_netsplit_join"> - <item quantity="one">Netsplit between %1$s and %2$s ended: %3$d user joined</item> - <item quantity="other">Netsplit between %1$s and %2$s ended: %3$d users joined</item> - </plurals> - <plurals name="message_netsplit_quit"> - <item quantity="one">Netsplit between %1$s and %2$s: %3$d user quit</item> - <item quantity="other">Netsplit between %1$s and %2$s: %3$d users quit</item> - </plurals> + <string name="label_cancel">Cancel</string> + <string name="label_clear_backlog">Clear Backlog</string> + <string name="label_delete">Delete</string> + <string name="label_disconnect">Disconnect</string> + <string name="label_drawer_close">Close</string> + <string name="label_drawer_open">Open</string> + <string name="label_filter_messages">Filter Messages</string> + <string name="label_save">Save</string> + <string name="label_select_multiple">Select</string> + <string name="label_settings">Settings</string> </resources> diff --git a/app/src/main/res/values/strings_messages.xml b/app/src/main/res/values/strings_messages.xml new file mode 100644 index 000000000..67ed8824c --- /dev/null +++ b/app/src/main/res/values/strings_messages.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="message_type_join">Join</string> + <string name="message_type_part">Part</string> + <string name="message_type_quit">Quit</string> + <string name="message_type_nick">Nick</string> + <string name="message_type_mode">Mode</string> + <string name="message_type_topic">Topic</string> + <string-array name="message_filter_types"> + <item>@string/message_type_join</item> + <item>@string/message_type_part</item> + <item>@string/message_type_quit</item> + <item>@string/message_type_nick</item> + <item>@string/message_type_mode</item> + <item>@string/message_type_topic</item> + </string-array> + + <string name="message_format_plain">%1$s%2$s: %3$s</string> + <string name="message_format_action">* %1$s%2$s %3$s</string> + <string name="message_format_notice">[%1$s%2$s] %3$s</string> + <string name="message_format_nick">%1$s%2$s is now known as %3$s%4$s</string> + <string name="message_format_mode">%1$s by %2$s%3$s</string> + <string name="message_format_join">%1$s%2$s joined</string> + <string name="message_format_part_1">%1$s%2$s left</string> + <string name="message_format_part_2">%1$s%2$s left: %3$s</string> + <string name="message_format_quit_1">%1$s%2$s quit</string> + <string name="message_format_quit_2">%1$s%2$s quit (%3$s)</string> + <plurals name="message_netsplit_join"> + <item quantity="one">Netsplit between %1$s and %2$s ended: %3$d user joined</item> + <item quantity="other">Netsplit between %1$s and %2$s ended: %3$d users joined</item> + </plurals> + <plurals name="message_netsplit_quit"> + <item quantity="one">Netsplit between %1$s and %2$s: %3$d user quit</item> + <item quantity="other">Netsplit between %1$s and %2$s: %3$d users quit</item> + </plurals> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values/preferences.xml b/app/src/main/res/values/strings_preferences.xml similarity index 98% rename from app/src/main/res/values/preferences.xml rename to app/src/main/res/values/strings_preferences.xml index 6af1e9c18..2ec76c925 100644 --- a/app/src/main/res/values/preferences.xml +++ b/app/src/main/res/values/strings_preferences.xml @@ -47,7 +47,7 @@ <string name="preference_show_prefix_key" translatable="false">show_prefix</string> <string name="preference_show_prefix_title">Show sendermodes</string> - <string name="preference_show_prefix_entry_all">Allv modes</string> + <string name="preference_show_prefix_entry_all">All modes</string> <string name="preference_show_prefix_entry_highest">Highest mode</string> <string name="preference_show_prefix_entry_none">No modes</string> <string-array name="preference_show_prefix_entries"> diff --git a/app/src/main/res/values/themes_quassel.xml b/app/src/main/res/values/themes_quassel.xml index aa5fab1c6..016983950 100644 --- a/app/src/main/res/values/themes_quassel.xml +++ b/app/src/main/res/values/themes_quassel.xml @@ -31,7 +31,7 @@ <item name="android:windowBackground">@color/quassel_light_background</item> <item name="colorBackground">#FAFAFA</item> - <item name="colorBackgroundHighlight">#FFA726</item> + <item name="colorBackgroundHighlight">#FFCA28</item> <item name="colorBackgroundSecondary">@null</item> <item name="colorBackgroundCard">#FFFFFF</item> <item name="colorBackgroundDialog">#FAFAFA</item> @@ -73,7 +73,7 @@ <item name="android:windowBackground">@color/quassel_dark_background</item> <item name="colorBackground">#303030</item> - <item name="colorBackgroundHighlight">#FFA726</item> + <item name="colorBackgroundHighlight">#FFCA28</item> <item name="colorBackgroundSecondary">@null</item> <item name="colorBackgroundCard">#424242</item> <item name="colorBackgroundDialog">#303030</item> diff --git a/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt index 59e57ea45..f2a29ec53 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt @@ -46,11 +46,14 @@ data class Flags<E>( } companion object { - inline fun <reified T> of(int: Int): Flags<T> where T : Flag<T>, T : Enum<T> - = Flags(int, enumValues()) - - inline fun <reified T> of(vararg flags: Flag<T>): Flags<T> where T : Flag<T>, T : Enum<T> - = Flags(flags.map(Flag<T>::bit).distinct().sum(), enumValues()) + inline fun <reified T> of(int: Int): Flags<T> where T : Flag<T>, T : Enum<T> = Flags( + int, enumValues() + ) + + inline fun <reified T> of( + vararg flags: Flag<T>): Flags<T> where T : Flag<T>, T : Enum<T> = Flags( + flags.map(Flag<T>::bit).distinct().sum(), enumValues() + ) } interface Factory<E> where E : Flag<E>, E : Enum<E> { @@ -67,28 +70,41 @@ infix fun <T> Flags<T>.hasFlag(which: T): Boolean where T : Enum<T>, T : Flag<T> return value and which.bit == which.bit } -infix fun <T> Flags<T>.or(other: Flag<T>): Flags<T> where T : kotlin.Enum<T>, T : Flag<T> = Flags( - value or other.bit -) +infix fun <T> Flags<T>.or(other: Int): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value or other) + +infix fun <T> Flags<T>.or(other: Flag<T>): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value or other.bit) + +infix fun <T> Flags<T>.or(other: Flags<T>): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value or other.value) + +infix fun <T> Flags<T>.and(other: Int): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value and other) + +infix fun <T> Flags<T>.and(other: Flag<T>): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value and other.bit) + +infix fun <T> Flags<T>.and(other: Flags<T>): Flags<T> + where T : kotlin.Enum<T>, T : Flag<T> = Flags(value and other.value) + +infix operator fun <T> Flags<T>.plus(other: Int): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value or other) -infix fun <T> Flags<T>.or(other: Flags<T>): Flags<T> where T : kotlin.Enum<T>, T : Flag<T> = Flags( - value or other.value -) +infix operator fun <T> Flags<T>.plus(other: Flag<T>): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value or other.bit) -infix fun <T> Flags<T>.and(other: Flag<T>): Flags<T> where T : kotlin.Enum<T>, T : Flag<T> = Flags( - value and other.bit -) +infix operator fun <T> Flags<T>.plus(other: Flags<T>): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value or other.value) -infix fun <T> Flags<T>.and(other: Flags<T>): Flags<T> where T : kotlin.Enum<T>, T : Flag<T> = Flags( - value and other.value -) +infix operator fun <T> Flags<T>.minus(other: Int): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value and other.inv()) -operator infix fun <T> Flags<T>.plus( - other: Flags<T>): Flags<T> where T : Enum<T>, T : Flag<T> = Flags(value or other.value) +infix operator fun <T> Flags<T>.minus(other: Flag<T>): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value and other.bit.inv()) -operator infix fun <T> Flags<T>.plus( - other: Flag<T>): Flags<T> where T : Enum<T>, T : Flag<T> = Flags(value or other.bit) +infix operator fun <T> Flags<T>.minus(other: Flags<T>): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value and other.value.inv()) -infix fun <T> Flags<T>.unset(which: T): Flags<T> where T : Enum<T>, T : Flag<T> = Flags( - value xor which.bit -) +infix fun <T> Flags<T>.unset(which: T): Flags<T> + where T : Enum<T>, T : Flag<T> = Flags(value xor which.bit) diff --git a/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt index 266f21eba..a2807b50c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt @@ -46,12 +46,13 @@ data class LongFlags<E>( } companion object { - inline fun <reified T> of(int: Long): LongFlags<T> where T : LongFlag<T>, T : Enum<T> - = LongFlags(int, enumValues()) + inline fun <reified T> of( + int: Long): LongFlags<T> where T : LongFlag<T>, T : Enum<T> = LongFlags(int, enumValues()) inline fun <reified T> of( - vararg flags: LongFlag<T>): LongFlags<T> where T : LongFlag<T>, T : Enum<T> - = LongFlags(flags.map(LongFlag<T>::bit).distinct().sum(), enumValues()) + vararg flags: LongFlag<T>): LongFlags<T> where T : LongFlag<T>, T : Enum<T> = LongFlags( + flags.map(LongFlag<T>::bit).distinct().sum(), enumValues() + ) } interface Factory<E> where E : LongFlag<E>, E : Enum<E> { @@ -67,37 +68,41 @@ infix fun <T> LongFlags<T>.hasFlag(which: T): Boolean where T : Enum<T>, T : Lon return value and which.bit == which.bit } -infix fun <T> LongFlags<T>.or( - other: LongFlag<T>): LongFlags<T> where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags( - value or other.bit -) - -infix fun <T> LongFlags<T>.or( - other: LongFlags<T>): LongFlags<T> where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags( - value or other.value -) - -infix fun <T> LongFlags<T>.and( - other: LongFlag<T>): LongFlags<T> where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags( - value and other.bit -) - -infix fun <T> LongFlags<T>.and( - other: LongFlags<T>): LongFlags<T> where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags( - value and other.value -) - -operator infix fun <T> LongFlags<T>.plus( - other: LongFlags<T>): LongFlags<T> where T : Enum<T>, T : LongFlag<T> = LongFlags( - value or other.value -) - -operator infix fun <T> LongFlags<T>.plus( - other: LongFlag<T>): LongFlags<T> where T : Enum<T>, T : LongFlag<T> = LongFlags( - value or other.bit -) - -infix fun <T> LongFlags<T>.unset( - which: T): LongFlags<T> where T : Enum<T>, T : LongFlag<T> = LongFlags( - value xor which.bit -) +infix fun <T> LongFlags<T>.or(other: Long): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value or other) + +infix fun <T> LongFlags<T>.or(other: LongFlag<T>): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value or other.bit) + +infix fun <T> LongFlags<T>.or(other: LongFlags<T>): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value or other.value) + +infix fun <T> LongFlags<T>.and(other: Long): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value and other) + +infix fun <T> LongFlags<T>.and(other: LongFlag<T>): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value and other.bit) + +infix fun <T> LongFlags<T>.and(other: LongFlags<T>): LongFlags<T> + where T : kotlin.Enum<T>, T : LongFlag<T> = LongFlags(value and other.value) + +infix operator fun <T> LongFlags<T>.plus(other: Long): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value or other) + +infix operator fun <T> LongFlags<T>.plus(other: LongFlag<T>): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value or other.bit) + +infix operator fun <T> LongFlags<T>.plus(other: LongFlags<T>): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value or other.value) + +infix operator fun <T> LongFlags<T>.minus(other: Long): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value and other.inv()) + +infix operator fun <T> LongFlags<T>.minus(other: LongFlag<T>): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value and other.bit.inv()) + +infix operator fun <T> LongFlags<T>.minus(other: LongFlags<T>): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value and other.value.inv()) + +infix fun <T> LongFlags<T>.unset(which: T): LongFlags<T> + where T : Enum<T>, T : LongFlag<T> = LongFlags(value xor which.bit) \ No newline at end of file diff --git a/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt index f5305d475..8f22a03bd 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt @@ -1,6 +1,7 @@ package de.kuschku.libquassel.util import kotlin.experimental.and +import kotlin.experimental.inv import kotlin.experimental.or import kotlin.experimental.xor @@ -71,37 +72,41 @@ infix fun <T> ShortFlags<T>.hasFlag(which: T): Boolean where T : Enum<T>, T : Sh return value and which.bit == which.bit } -infix fun <T> ShortFlags<T>.or( - other: ShortFlag<T>): ShortFlags<T> where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags( - value or other.bit -) - -infix fun <T> ShortFlags<T>.or( - other: ShortFlags<T>): ShortFlags<T> where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags( - value or other.value -) - -infix fun <T> ShortFlags<T>.and( - other: ShortFlag<T>): ShortFlags<T> where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags( - value and other.bit -) - -infix fun <T> ShortFlags<T>.and( - other: ShortFlags<T>): ShortFlags<T> where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags( - value and other.value -) - -operator infix fun <T> ShortFlags<T>.plus( - other: ShortFlags<T>): ShortFlags<T> where T : Enum<T>, T : ShortFlag<T> = ShortFlags( - value or other.value -) - -operator infix fun <T> ShortFlags<T>.plus( - other: ShortFlag<T>): ShortFlags<T> where T : Enum<T>, T : ShortFlag<T> = ShortFlags( - value or other.bit -) - -infix fun <T> ShortFlags<T>.unset( - which: T): ShortFlags<T> where T : Enum<T>, T : ShortFlag<T> = ShortFlags( - value xor which.bit -) +infix fun <T> ShortFlags<T>.or(other: Short): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value or other) + +infix fun <T> ShortFlags<T>.or(other: ShortFlag<T>): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value or other.bit) + +infix fun <T> ShortFlags<T>.or(other: ShortFlags<T>): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value or other.value) + +infix fun <T> ShortFlags<T>.and(other: Short): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value and other) + +infix fun <T> ShortFlags<T>.and(other: ShortFlag<T>): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value and other.bit) + +infix fun <T> ShortFlags<T>.and(other: ShortFlags<T>): ShortFlags<T> + where T : kotlin.Enum<T>, T : ShortFlag<T> = ShortFlags(value and other.value) + +infix operator fun <T> ShortFlags<T>.plus(other: Short): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value or other) + +infix operator fun <T> ShortFlags<T>.plus(other: ShortFlag<T>): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value or other.bit) + +infix operator fun <T> ShortFlags<T>.plus(other: ShortFlags<T>): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value or other.value) + +infix operator fun <T> ShortFlags<T>.minus(other: Short): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value and other.inv()) + +infix operator fun <T> ShortFlags<T>.minus(other: ShortFlag<T>): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value and other.bit.inv()) + +infix operator fun <T> ShortFlags<T>.minus(other: ShortFlags<T>): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value and other.value.inv()) + +infix fun <T> ShortFlags<T>.unset(which: T): ShortFlags<T> + where T : Enum<T>, T : ShortFlag<T> = ShortFlags(value xor which.bit) \ No newline at end of file -- GitLab