Minor fixes and improvements

This commit is contained in:
Christian Basler 2017-09-22 20:29:23 +02:00
parent c1d74e4781
commit f27f438998
11 changed files with 51 additions and 77 deletions

View File

@ -29,7 +29,6 @@ import ch.dissem.apps.abit.drawer.ProfileImageListener
import ch.dissem.apps.abit.drawer.ProfileSelectionListener import ch.dissem.apps.abit.drawer.ProfileSelectionListener
import ch.dissem.apps.abit.listener.ListSelectionListener import ch.dissem.apps.abit.listener.ListSelectionListener
import ch.dissem.apps.abit.repository.AndroidMessageRepository.Companion.LABEL_ARCHIVE import ch.dissem.apps.abit.repository.AndroidMessageRepository.Companion.LABEL_ARCHIVE
import ch.dissem.apps.abit.service.BitmessageService.Companion.isRunning
import ch.dissem.apps.abit.service.Singleton import ch.dissem.apps.abit.service.Singleton
import ch.dissem.apps.abit.synchronization.SyncAdapter import ch.dissem.apps.abit.synchronization.SyncAdapter
import ch.dissem.apps.abit.util.Labels import ch.dissem.apps.abit.util.Labels
@ -99,8 +98,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
private lateinit var drawer: Drawer private lateinit var drawer: Drawer
private lateinit var nodeSwitch: SwitchDrawerItem private lateinit var nodeSwitch: SwitchDrawerItem
val floatingActionButton: FabSpeedDial val floatingActionButton: FabSpeedDial?
get() = fab get() = findViewById(R.id.fab) as FabSpeedDial?
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -359,11 +358,12 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
} }
override fun onRestoreInstanceState(savedInstanceState: Bundle) { override fun onRestoreInstanceState(savedInstanceState: Bundle) {
selectedLabel = savedInstanceState.getSerializable("selectedLabel") as Label selectedLabel = savedInstanceState.getSerializable("selectedLabel") as Label?
val selectedItem = drawer.getDrawerItem(selectedLabel) selectedLabel?.let { selectedLabel ->
if (selectedItem != null) { drawer.getDrawerItem(selectedLabel)?.let { selectedItem ->
drawer.setSelection(selectedItem) drawer.setSelection(selectedItem)
}
} }
super.onRestoreInstanceState(savedInstanceState) super.onRestoreInstanceState(savedInstanceState)
} }

View File

@ -111,14 +111,7 @@ class MessageDetailFragment : Fragment() {
text.linksClickable = true text.linksClickable = true
text.setTextIsSelectable(true) text.setTextIsSelectable(true)
var removed = false val removed = item.labels.removeAll { it.type==Label.Type.UNREAD }
val labels = item.labels.iterator()
while (labels.hasNext()) {
if (labels.next().type == Label.Type.UNREAD) {
labels.remove()
removed = true
}
}
val messageRepo = Singleton.getMessageRepository(context) val messageRepo = Singleton.getMessageRepository(context)
if (removed) { if (removed) {
if (activity is MainActivity) { if (activity is MainActivity) {
@ -173,15 +166,14 @@ class MessageDetailFragment : Fragment() {
Singleton.labeler.delete(item) Singleton.labeler.delete(item)
messageRepo.save(item) messageRepo.save(item)
} }
(activity as? MainActivity)?.updateUnread()
activity.onBackPressed() activity.onBackPressed()
return true return true
} }
R.id.mark_unread -> { R.id.mark_unread -> {
Singleton.labeler.markAsUnread(item) Singleton.labeler.markAsUnread(item)
messageRepo.save(item) messageRepo.save(item)
if (activity is MainActivity) { (activity as? MainActivity)?.updateUnread()
(activity as MainActivity).updateUnread()
}
return true return true
} }
R.id.archive -> { R.id.archive -> {
@ -190,6 +182,7 @@ class MessageDetailFragment : Fragment() {
} }
Singleton.labeler.archive(item) Singleton.labeler.archive(item)
messageRepo.save(item) messageRepo.save(item)
(activity as? MainActivity)?.updateUnread()
return true return true
} }
else -> return false else -> return false

View File

@ -16,9 +16,8 @@
package ch.dissem.apps.abit package ch.dissem.apps.abit
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
@ -32,7 +31,6 @@ import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter
import ch.dissem.apps.abit.listener.ListSelectionListener import ch.dissem.apps.abit.listener.ListSelectionListener
import ch.dissem.apps.abit.repository.AndroidMessageRepository import ch.dissem.apps.abit.repository.AndroidMessageRepository
import ch.dissem.apps.abit.repository.AndroidMessageRepository.Companion.LABEL_ARCHIVE
import ch.dissem.apps.abit.service.Singleton import ch.dissem.apps.abit.service.Singleton
import ch.dissem.apps.abit.util.FabUtils import ch.dissem.apps.abit.util.FabUtils
import ch.dissem.bitmessage.entity.Plaintext import ch.dissem.bitmessage.entity.Plaintext
@ -186,18 +184,17 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
adapter.eventListener = object : SwipeableMessageAdapter.EventListener { adapter.eventListener = object : SwipeableMessageAdapter.EventListener {
override fun onItemDeleted(item: Plaintext) { override fun onItemDeleted(item: Plaintext) {
if (MessageDetailFragment.isInTrash(item)) { if (MessageDetailFragment.isInTrash(item)) {
Singleton.labeler.delete(item)
messageRepo.remove(item) messageRepo.remove(item)
} else { } else {
item.labels.clear() Singleton.labeler.delete(item)
item.addLabels(messageRepo.getLabels(Label.Type.TRASH))
messageRepo.save(item) messageRepo.save(item)
} }
recyclerViewOnScrollListener.onScrolled(null, 0, 0) recyclerViewOnScrollListener.onScrolled(null, 0, 0)
} }
override fun onItemArchived(item: Plaintext) { override fun onItemArchived(item: Plaintext) {
item.labels.clear() Singleton.labeler.archive(item)
messageRepo.save(item)
recyclerViewOnScrollListener.onScrolled(null, 0, 0) recyclerViewOnScrollListener.onScrolled(null, 0, 0)
} }
@ -242,19 +239,29 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
this.swipeableMessageAdapter = adapter this.swipeableMessageAdapter = adapter
Singleton.labeler.listener = { message, added, removed -> Singleton.labeler.listener = { message, added, removed ->
if (currentLabel?.type == Label.Type.TRASH && added.all { it.type == Label.Type.TRASH } && removed.isEmpty()) { when {
// work-around for messages that are deleted from trash currentLabel?.type == Label.Type.TRASH && added.all { it.type == Label.Type.TRASH } && removed.any { it.type == Label.Type.TRASH } -> {
swipeableMessageAdapter?.remove(message) // work-around for messages that are deleted from trash
recyclerViewOnScrollListener.onScrolled(null, 0, 0) swipeableMessageAdapter?.remove(message)
} else if (added.contains(currentLabel)) { recyclerViewOnScrollListener.onScrolled(null, 0, 0)
// in most cases, top should be the correct position, but time will show if }
// the message should be properly sorted in currentLabel?.type == Label.Type.UNREAD && added.all { it.type == Label.Type.TRASH } -> {
swipeableMessageAdapter?.addFirst(message) // work-around for messages that are deleted from unread, which already have the unread label removed
} else if (removed.contains(currentLabel)) { swipeableMessageAdapter?.remove(message)
swipeableMessageAdapter?.remove(message) recyclerViewOnScrollListener.onScrolled(null, 0, 0)
recyclerViewOnScrollListener.onScrolled(null, 0, 0) }
} else if (removed.any { it.type == Label.Type.UNREAD } || added.any { it.type == Label.Type.UNREAD }) { added.contains(currentLabel) -> {
swipeableMessageAdapter?.update(message) // in most cases, top should be the correct position, but time will show if
// the message should be properly sorted in
swipeableMessageAdapter?.addFirst(message)
}
removed.contains(currentLabel) -> {
swipeableMessageAdapter?.remove(message)
recyclerViewOnScrollListener.onScrolled(null, 0, 0)
}
removed.any { it.type == Label.Type.UNREAD } || added.any { it.type == Label.Type.UNREAD } -> {
swipeableMessageAdapter?.update(message)
}
} }
} }
} }
@ -348,10 +355,4 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
true true
} }
} }
fun addMessage(message: Plaintext) {
if (message.labels.contains(currentLabel) || (currentLabel == LABEL_ARCHIVE && message.labels.isEmpty())) {
swipeableMessageAdapter?.addFirst(message)
}
}
} }

View File

@ -19,42 +19,18 @@ package ch.dissem.apps.abit.listener
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkInfo
import ch.dissem.apps.abit.service.BitmessageService import ch.dissem.apps.abit.service.BitmessageService
import ch.dissem.apps.abit.service.Singleton import ch.dissem.apps.abit.service.Singleton
import ch.dissem.apps.abit.util.Preferences import ch.dissem.apps.abit.util.Preferences
import org.jetbrains.anko.connectivityManager
class WifiReceiver : BroadcastReceiver() { class WifiReceiver : BroadcastReceiver() {
override fun onReceive(ctx: Context, intent: Intent) { override fun onReceive(ctx: Context, intent: Intent) {
if ("android.net.conn.CONNECTIVITY_CHANGE" == intent.action) { if ("android.net.conn.CONNECTIVITY_CHANGE" == intent.action) {
val bmc = Singleton.getBitmessageContext(ctx) val bmc = Singleton.getBitmessageContext(ctx)
if (Preferences.isWifiOnly(ctx) && isConnectedToMeteredNetwork(ctx) && bmc.isRunning()) { if (Preferences.isFullNodeActive(ctx) && !bmc.isRunning() && !(Preferences.isWifiOnly(ctx) && ctx.connectivityManager.isActiveNetworkMetered)) {
bmc.shutdown()
}
if (Preferences.isFullNodeActive(ctx) && !bmc.isRunning() && !(Preferences.isWifiOnly(ctx) && isConnectedToMeteredNetwork(ctx))) {
ctx.startService(Intent(ctx, BitmessageService::class.java)) ctx.startService(Intent(ctx, BitmessageService::class.java))
} }
} }
} }
companion object {
fun isConnectedToMeteredNetwork(ctx: Context): Boolean {
val netInfo = getNetworkInfo(ctx)
if (netInfo == null || !netInfo.isConnectedOrConnecting) {
return false
}
when (netInfo.type) {
ConnectivityManager.TYPE_ETHERNET, ConnectivityManager.TYPE_WIFI -> return false
else -> return true
}
}
private fun getNetworkInfo(ctx: Context): NetworkInfo? {
val conMan = ctx.getSystemService(Context
.CONNECTIVITY_SERVICE) as ConnectivityManager
return conMan.activeNetworkInfo
}
}
} }

View File

@ -11,7 +11,7 @@ import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
*/ */
object FabUtils { object FabUtils {
fun initFab(activity: MainActivity, @DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial { fun initFab(activity: MainActivity, @DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial {
val fab = activity.floatingActionButton val fab = activity.floatingActionButton ?: throw IllegalStateException("Fab must not be null")
fab.removeAllOnMenuItemClickListeners() fab.removeAllOnMenuItemClickListeners()
fab.show() fab.show()
fab.closeMenu() fab.closeMenu()

View File

@ -26,6 +26,8 @@ import ch.dissem.apps.abit.util.Constants.PREFERENCE_REQUEST_ACK
import ch.dissem.apps.abit.util.Constants.PREFERENCE_SYNC_TIMEOUT import ch.dissem.apps.abit.util.Constants.PREFERENCE_SYNC_TIMEOUT
import ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE import ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE
import ch.dissem.apps.abit.util.Constants.PREFERENCE_WIFI_ONLY import ch.dissem.apps.abit.util.Constants.PREFERENCE_WIFI_ONLY
import org.jetbrains.anko.connectivityManager
import org.jetbrains.anko.networkStatsManager
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
@ -88,7 +90,7 @@ object Preferences {
return preferences.getString(name, null) return preferences.getString(name, null)
} }
fun isConnectionAllowed(ctx: Context) = !isWifiOnly(ctx) || !WifiReceiver.isConnectedToMeteredNetwork(ctx) fun isConnectionAllowed(ctx: Context) = !isWifiOnly(ctx) || ctx.connectivityManager.isActiveNetworkMetered
fun isWifiOnly(ctx: Context): Boolean { fun isWifiOnly(ctx: Context): Boolean {
val preferences = PreferenceManager.getDefaultSharedPreferences(ctx) val preferences = PreferenceManager.getDefaultSharedPreferences(ctx)

View File

@ -18,7 +18,6 @@
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingBottom="18dp" android:paddingBottom="18dp"
@ -71,7 +70,7 @@
android:text="@string/ok" android:text="@string/ok"
android:textColor="@color/colorAccent" android:textColor="@color/colorAccent"
app:layout_constraintHorizontal_bias="1.0" app:layout_constraintHorizontal_bias="1.0"
android:layout_alignRight="@+id/radioGroup" android:layout_alignEnd="@+id/radioGroup"
android:layout_below="@+id/radioGroup"/> android:layout_below="@+id/radioGroup"/>
<Button <Button
@ -81,7 +80,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/cancel" android:text="@string/cancel"
android:textColor="@color/colorAccent" android:textColor="@color/colorAccent"
android:layout_toLeftOf="@+id/ok" android:layout_toStartOf="@+id/ok"
android:layout_below="@+id/radioGroup"/> android:layout_below="@+id/radioGroup"/>
</RelativeLayout> </RelativeLayout>

View File

@ -31,7 +31,6 @@
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:text="CheckBox"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Name"/> tools:text="Name"/>

View File

@ -10,6 +10,6 @@
android:id="@+id/select_encoding" android:id="@+id/select_encoding"
app:showAsAction="never" app:showAsAction="never"
android:icon="@drawable/ic_action_encoding" android:icon="@drawable/ic_action_encoding"
android:title="Select encoding" android:title="@string/select_encoding"
/> />
</menu> </menu>

View File

@ -124,4 +124,7 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
<string name="request_acknowledgements">Bestätigungen verlangen</string> <string name="request_acknowledgements">Bestätigungen verlangen</string>
<string name="request_acknowledgements_summary">Bestätigungen stellen sicher dass eine Nachricht empfangen wurde, benötigen aber zusätzliche Zeit zum versenden</string> <string name="request_acknowledgements_summary">Bestätigungen stellen sicher dass eine Nachricht empfangen wurde, benötigen aber zusätzliche Zeit zum versenden</string>
<string name="got_it">Alles klar</string> <string name="got_it">Alles klar</string>
<string name="import_data">Import</string>
<string name="import_data_summary">Nachrichten und Kontakte importieren (aber keine Identitäten)</string>
<string name="select_encoding">Kodierung auswählen</string>
</resources> </resources>

View File

@ -125,4 +125,5 @@ As an alternative you could configure a trusted node in the settings, but as of
<string name="request_acknowledgements">Request acknowledgements</string> <string name="request_acknowledgements">Request acknowledgements</string>
<string name="request_acknowledgements_summary">Acknowledges allow making sure a message was received, but require additional time to send</string> <string name="request_acknowledgements_summary">Acknowledges allow making sure a message was received, but require additional time to send</string>
<string name="got_it">Got it</string> <string name="got_it">Got it</string>
<string name="select_encoding">Select encoding</string>
</resources> </resources>